Coverage Report

Created: 2025-06-24 07:14

/src/libsmraw/libsmraw/libsmraw_handle.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Handle functions
3
 *
4
 * Copyright (C) 2010-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 <narrow_string.h>
25
#include <system_string.h>
26
#include <types.h>
27
#include <wide_string.h>
28
29
#include "libsmraw_definitions.h"
30
#include "libsmraw_handle.h"
31
#include "libsmraw_information_file.h"
32
#include "libsmraw_io_handle.h"
33
#include "libsmraw_libbfio.h"
34
#include "libsmraw_libcerror.h"
35
#include "libsmraw_libcnotify.h"
36
#include "libsmraw_libcthreads.h"
37
#include "libsmraw_libfdata.h"
38
#include "libsmraw_libfvalue.h"
39
#include "libsmraw_libuna.h"
40
#include "libsmraw_types.h"
41
42
/* Creates a handle
43
 * Make sure the value handle is referencing, is set to NULL
44
 * Returns 1 if successful or -1 on error
45
 */
46
int libsmraw_handle_initialize(
47
     libsmraw_handle_t **handle,
48
     libcerror_error_t **error )
49
22
{
50
22
  libsmraw_internal_handle_t *internal_handle = NULL;
51
22
  static char *function                       = "libsmraw_handle_initialize";
52
53
22
  if( handle == NULL )
54
0
  {
55
0
    libcerror_error_set(
56
0
     error,
57
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
58
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
59
0
     "%s: invalid handle.",
60
0
     function );
61
62
0
    return( -1 );
63
0
  }
64
22
  if( *handle != NULL )
65
0
  {
66
0
    libcerror_error_set(
67
0
     error,
68
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
69
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
70
0
     "%s: invalid handle value already set.",
71
0
     function );
72
73
0
    return( -1 );
74
0
  }
75
22
  internal_handle = memory_allocate_structure(
76
22
                     libsmraw_internal_handle_t );
77
78
22
  if( internal_handle == NULL )
79
0
  {
80
0
    libcerror_error_set(
81
0
     error,
82
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
83
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
84
0
     "%s: unable to create internal handle.",
85
0
     function );
86
87
0
    goto on_error;
88
0
  }
89
22
  if( memory_set(
90
22
       internal_handle,
91
22
       0,
92
22
       sizeof( libsmraw_internal_handle_t ) ) == NULL )
93
0
  {
94
0
    libcerror_error_set(
95
0
     error,
96
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
97
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
98
0
     "%s: unable to clear handle.",
99
0
     function );
100
101
0
    memory_free(
102
0
     internal_handle );
103
104
0
    return( -1 );
105
0
  }
106
22
  if( libsmraw_io_handle_initialize(
107
22
       &( internal_handle->io_handle ),
108
22
       error ) != 1 )
109
0
  {
110
0
    libcerror_error_set(
111
0
     error,
112
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
113
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
114
0
     "%s: unable to create IO handle.",
115
0
     function );
116
117
0
    goto on_error;
118
0
  }
119
22
  if( libfvalue_table_initialize(
120
22
       &( internal_handle->media_values ),
121
22
       0,
122
22
       error ) != 1 )
123
0
  {
124
0
    libcerror_error_set(
125
0
     error,
126
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
127
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
128
0
     "%s: unable to create media values table.",
129
0
     function );
130
131
0
    goto on_error;
132
0
  }
133
22
  if( libfvalue_table_initialize(
134
22
       &( internal_handle->information_values ),
135
22
       0,
136
22
       error ) != 1 )
137
0
  {
138
0
    libcerror_error_set(
139
0
     error,
140
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
141
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
142
0
     "%s: unable to create information values table.",
143
0
     function );
144
145
0
    goto on_error;
146
0
  }
147
22
  if( libfvalue_table_initialize(
148
22
       &( internal_handle->integrity_hash_values ),
149
22
       0,
150
22
       error ) != 1 )
151
0
  {
152
0
    libcerror_error_set(
153
0
     error,
154
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
155
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
156
0
     "%s: unable to create integrity hash values table.",
157
0
     function );
158
159
0
    goto on_error;
160
0
  }
161
22
#if defined( HAVE_LIBSMRAW_MULTI_THREAD_SUPPORT )
162
22
  if( libcthreads_read_write_lock_initialize(
163
22
       &( internal_handle->read_write_lock ),
164
22
       error ) != 1 )
165
0
  {
166
0
    libcerror_error_set(
167
0
     error,
168
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
169
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
170
0
     "%s: unable to initialize read/write lock.",
171
0
     function );
172
173
0
    goto on_error;
174
0
  }
175
22
#endif
176
22
  internal_handle->maximum_number_of_open_handles = LIBBFIO_POOL_UNLIMITED_NUMBER_OF_OPEN_HANDLES;
177
178
22
  *handle = (libsmraw_handle_t *) internal_handle;
179
180
22
  return( 1 );
181
182
0
on_error:
183
0
  if( internal_handle != NULL )
184
0
  {
185
0
    if( internal_handle->integrity_hash_values != NULL )
186
0
    {
187
0
      libfvalue_table_free(
188
0
       &( internal_handle->integrity_hash_values ),
189
0
       NULL );
190
0
    }
191
0
    if( internal_handle->information_values != NULL )
192
0
    {
193
0
      libfvalue_table_free(
194
0
       &( internal_handle->information_values ),
195
0
       NULL );
196
0
    }
197
0
    if( internal_handle->media_values != NULL )
198
0
    {
199
0
      libfvalue_table_free(
200
0
       &( internal_handle->media_values ),
201
0
       NULL );
202
0
    }
203
0
    if( internal_handle->io_handle != NULL )
204
0
    {
205
0
      libsmraw_io_handle_free(
206
0
       &( internal_handle->io_handle ),
207
0
       NULL );
208
0
    }
209
0
    memory_free(
210
0
     internal_handle );
211
0
  }
212
0
  return( -1 );
213
214
22
}
215
216
/* Frees a handle
217
 * Returns 1 if succesful or -1 on error
218
 */
219
int libsmraw_handle_free(
220
     libsmraw_handle_t **handle,
221
     libcerror_error_t **error )
222
22
{
223
22
  libsmraw_internal_handle_t *internal_handle = NULL;
224
22
  static char *function                       = "libsmraw_internal_handle_free";
225
22
  int result                                  = 1;
226
227
22
  if( handle == NULL )
228
0
  {
229
0
    libcerror_error_set(
230
0
     error,
231
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
232
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
233
0
     "%s: invalid handle.",
234
0
     function );
235
236
0
    return( -1 );
237
0
  }
238
22
  if( *handle != NULL )
239
22
  {
240
22
    internal_handle = (libsmraw_internal_handle_t *) *handle;
241
242
22
    if( internal_handle->file_io_pool != NULL )
243
0
    {
244
0
      if( libsmraw_handle_close(
245
0
           *handle,
246
0
           error ) != 0 )
247
0
      {
248
0
        libcerror_error_set(
249
0
         error,
250
0
         LIBCERROR_ERROR_DOMAIN_IO,
251
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
252
0
         "%s: unable to close handle.",
253
0
         function );
254
255
0
        result = -1;
256
0
      }
257
0
    }
258
22
    *handle = NULL;
259
260
22
#if defined( HAVE_LIBSMRAW_MULTI_THREAD_SUPPORT )
261
22
    if( libcthreads_read_write_lock_free(
262
22
         &( internal_handle->read_write_lock ),
263
22
         error ) != 1 )
264
0
    {
265
0
      libcerror_error_set(
266
0
       error,
267
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
268
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
269
0
       "%s: unable to free read/write lock.",
270
0
       function );
271
272
0
      result = -1;
273
0
    }
274
22
#endif
275
22
    if( libsmraw_io_handle_free(
276
22
         &( internal_handle->io_handle ),
277
22
         error ) != 1 )
278
0
    {
279
0
      libcerror_error_set(
280
0
       error,
281
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
282
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
283
0
       "%s: unable to free IO handle.",
284
0
       function );
285
286
0
      result = -1;
287
0
    }
288
22
    if( libfvalue_table_free(
289
22
         &( internal_handle->media_values ),
290
22
         error ) != 1 )
291
0
    {
292
0
      libcerror_error_set(
293
0
       error,
294
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
295
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
296
0
       "%s: unable to free media values table.",
297
0
       function );
298
299
0
      result = -1;
300
0
    }
301
22
    if( libfvalue_table_free(
302
22
         &( internal_handle->information_values ),
303
22
         error ) != 1 )
304
0
    {
305
0
      libcerror_error_set(
306
0
       error,
307
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
308
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
309
0
       "%s: unable to free information values table.",
310
0
       function );
311
312
0
      result = -1;
313
0
    }
314
22
    if( libfvalue_table_free(
315
22
         &( internal_handle->integrity_hash_values ),
316
22
         error ) != 1 )
317
0
    {
318
0
      libcerror_error_set(
319
0
       error,
320
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
321
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
322
0
       "%s: unable to free integrity hash values table.",
323
0
       function );
324
325
0
      result = -1;
326
0
    }
327
22
    memory_free(
328
22
     internal_handle );
329
22
  }
330
22
  return( result );
331
22
}
332
333
/* Signals the handle to abort its current activity
334
 * Returns 1 if successful or -1 on error
335
 */
336
int libsmraw_handle_signal_abort(
337
     libsmraw_handle_t *handle,
338
     libcerror_error_t **error )
339
0
{
340
0
  libsmraw_internal_handle_t *internal_handle = NULL;
341
0
  static char *function                       = "libsmraw_handle_signal_abort";
342
343
0
  if( handle == NULL )
344
0
  {
345
0
    libcerror_error_set(
346
0
     error,
347
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
348
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
349
0
     "%s: invalid handle.",
350
0
     function );
351
352
0
    return( -1 );
353
0
  }
354
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
355
356
0
  if( internal_handle->io_handle == NULL )
357
0
  {
358
0
    libcerror_error_set(
359
0
     error,
360
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
361
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
362
0
     "%s: invalid handle - missing IO handle.",
363
0
     function );
364
365
0
    return( -1 );
366
0
  }
367
0
  internal_handle->io_handle->abort = 1;
368
369
0
  return( 1 );
370
0
}
371
372
/* Initializes the write values
373
 * Returns 1 if successful or -1 on error
374
 */
375
int libsmraw_internal_handle_initialize_write_values(
376
     libsmraw_internal_handle_t *internal_handle,
377
     libcerror_error_t **error )
378
0
{
379
0
  static char *function       = "libsmraw_internal_handle_initialize_write_values";
380
0
  size64_t last_segment_size  = 0;
381
0
  size64_t number_of_segments = 0;
382
383
0
  if( internal_handle == NULL )
384
0
  {
385
0
    libcerror_error_set(
386
0
     error,
387
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
388
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
389
0
     "%s: invalid handle.",
390
0
     function );
391
392
0
    return( -1 );
393
0
  }
394
0
  if( internal_handle->io_handle == NULL )
395
0
  {
396
0
    libcerror_error_set(
397
0
     error,
398
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
399
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
400
0
     "%s: invalid handle - missing IO handle.",
401
0
     function );
402
403
0
    return( -1 );
404
0
  }
405
0
  if( internal_handle->write_values_initialized != 0 )
406
0
  {
407
0
    libcerror_error_set(
408
0
     error,
409
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
410
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
411
0
     "%s: write values were initialized and cannot be initialized anymore.",
412
0
     function );
413
414
0
    return( -1 );
415
0
  }
416
0
  if( internal_handle->io_handle->maximum_segment_size == 0 )
417
0
  {
418
0
    internal_handle->io_handle->number_of_segments = 1;
419
0
  }
420
0
  else if( internal_handle->io_handle->media_size == 0 )
421
0
  {
422
0
    internal_handle->io_handle->number_of_segments = 0;
423
0
  }
424
0
  else
425
0
  {
426
0
    number_of_segments = internal_handle->io_handle->media_size
427
0
                       / internal_handle->io_handle->maximum_segment_size;
428
429
0
    last_segment_size = internal_handle->io_handle->media_size
430
0
                      % internal_handle->io_handle->maximum_segment_size;
431
432
0
    if( last_segment_size != 0 )
433
0
    {
434
0
      number_of_segments += 1;
435
0
    }
436
0
    if( number_of_segments > (size64_t) INT_MAX )
437
0
    {
438
0
      libcerror_error_set(
439
0
       error,
440
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
441
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
442
0
       "%s: invalid number of segments value out of bounds.",
443
0
       function );
444
445
0
      return( -1 );
446
0
    }
447
0
    internal_handle->io_handle->number_of_segments = (int) number_of_segments;
448
0
  }
449
0
  internal_handle->write_values_initialized = 1;
450
451
0
  return( 1 );
452
0
}
453
454
/* Opens a set of storage media RAW files
455
 * Returns 1 if successful or -1 on error
456
 */
457
int libsmraw_handle_open(
458
     libsmraw_handle_t *handle,
459
     char * const filenames[],
460
     int number_of_filenames,
461
     int access_flags,
462
     libcerror_error_t **error )
463
0
{
464
0
  libbfio_handle_t *file_io_handle            = NULL;
465
0
  libbfio_pool_t *file_io_pool                = NULL;
466
0
  libsmraw_internal_handle_t *internal_handle = NULL;
467
0
  system_character_t *information_filename    = NULL;
468
0
  static char *function                       = "libsmraw_handle_open";
469
0
  size_t filename_index                       = 0;
470
0
  size_t filename_length                      = 0;
471
0
  size_t information_filename_length          = 0;
472
0
  int bfio_access_flags                       = 0;
473
0
  int filename_iterator                       = 0;
474
475
0
  if( handle == NULL )
476
0
  {
477
0
    libcerror_error_set(
478
0
     error,
479
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
480
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
481
0
     "%s: invalid handle.",
482
0
     function );
483
484
0
    return( -1 );
485
0
  }
486
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
487
488
0
  if( internal_handle->io_handle == NULL )
489
0
  {
490
0
    libcerror_error_set(
491
0
     error,
492
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
493
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
494
0
     "%s: invalid handle - missing IO handle.",
495
0
     function );
496
497
0
    return( -1 );
498
0
  }
499
0
  if( internal_handle->file_io_pool != NULL )
500
0
  {
501
0
    libcerror_error_set(
502
0
     error,
503
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
504
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
505
0
     "%s: invalid handle - file IO pool value already set.",
506
0
     function );
507
508
0
    return( -1 );
509
0
  }
510
0
  if( internal_handle->information_file != NULL )
511
0
  {
512
0
    libcerror_error_set(
513
0
     error,
514
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
515
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
516
0
     "%s: invalid handle - information file value already set.",
517
0
     function );
518
519
0
    return( -1 );
520
0
  }
521
0
  if( filenames == NULL )
522
0
  {
523
0
    libcerror_error_set(
524
0
     error,
525
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
526
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
527
0
     "%s: invalid filenames.",
528
0
     function );
529
530
0
    return( -1 );
531
0
  }
532
0
  if( number_of_filenames <= 0 )
533
0
  {
534
0
    libcerror_error_set(
535
0
     error,
536
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
537
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
538
0
     "%s: invalid number of filenames value out of bounds.",
539
0
     function );
540
541
0
    return( -1 );
542
0
  }
543
0
  if( ( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) == 0 )
544
0
   && ( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) == 0 ) )
545
0
  {
546
0
    libcerror_error_set(
547
0
     error,
548
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
549
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
550
0
     "%s: unsupported access flags.",
551
0
     function );
552
553
0
    return( -1 );
554
0
  }
555
  /* Open for read only or read/write
556
   */
557
0
  if( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) != 0 )
558
0
  {
559
0
    if( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) != 0 )
560
0
    {
561
0
      bfio_access_flags |= LIBBFIO_ACCESS_FLAG_READ;
562
0
    }
563
0
    if( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) != 0 )
564
0
    {
565
0
      bfio_access_flags |= LIBBFIO_ACCESS_FLAG_WRITE;
566
0
    }
567
    /* Set the basename
568
     */
569
0
    filename_length = narrow_string_length(
570
0
           filenames[ 0 ] );
571
572
0
    if( filename_length <= 4 )
573
0
    {
574
0
      libcerror_error_set(
575
0
       error,
576
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
577
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
578
0
       "%s: missing basename.",
579
0
       function );
580
581
0
      goto on_error;
582
0
    }
583
0
    if( libsmraw_io_handle_set_basename(
584
0
         internal_handle->io_handle,
585
0
         filenames[ 0 ],
586
0
         filename_length - 4,
587
0
         error ) != 1 )
588
0
    {
589
0
      libcerror_error_set(
590
0
       error,
591
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
592
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
593
0
       "%s: unable to set basename.",
594
0
      function );
595
596
0
      goto on_error;
597
0
    }
598
0
    if( libbfio_pool_initialize(
599
0
         &file_io_pool,
600
0
         number_of_filenames,
601
0
         internal_handle->maximum_number_of_open_handles,
602
0
         error ) != 1 )
603
0
    {
604
0
      libcerror_error_set(
605
0
       error,
606
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
607
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
608
0
       "%s: unable to create file IO pool.",
609
0
       function );
610
611
0
      goto on_error;
612
0
    }
613
0
    for( filename_iterator = 0;
614
0
         filename_iterator < number_of_filenames;
615
0
         filename_iterator++ )
616
0
    {
617
0
      filename_length = narrow_string_length(
618
0
             filenames[ filename_iterator ] );
619
620
0
      if( filename_length == 0 )
621
0
      {
622
0
        libcerror_error_set(
623
0
         error,
624
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
625
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
626
0
         "%s: missing filename: %d.",
627
0
         function,
628
0
         filename_iterator );
629
630
0
        goto on_error;
631
0
      }
632
0
      if( libbfio_file_initialize(
633
0
           &file_io_handle,
634
0
           error ) != 1 )
635
0
      {
636
0
        libcerror_error_set(
637
0
         error,
638
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
639
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
640
0
         "%s: unable to create file IO handle: %d.",
641
0
         function,
642
0
         filename_iterator );
643
644
0
        goto on_error;
645
0
      }
646
#if defined( HAVE_DEBUG_OUTPUT )
647
      if( libbfio_handle_set_track_offsets_read(
648
           file_io_handle,
649
           1,
650
           error ) != 1 )
651
      {
652
                    libcerror_error_set(
653
                     error,
654
                     LIBCERROR_ERROR_DOMAIN_RUNTIME,
655
                     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
656
                     "%s: unable to set track offsets read in file IO handle: %d.",
657
                     function,
658
         filename_iterator );
659
660
        goto on_error;
661
      }
662
#endif
663
0
      if( libbfio_file_set_name(
664
0
           file_io_handle,
665
0
           filenames[ filename_iterator ],
666
0
           filename_length + 1,
667
0
           error ) != 1 )
668
0
      {
669
0
        libcerror_error_set(
670
0
         error,
671
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
672
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
673
0
         "%s: unable to set name in file IO handle: %d.",
674
0
         function,
675
0
         filename_iterator );
676
677
0
        goto on_error;
678
0
      }
679
0
      if( libbfio_pool_set_handle(
680
0
           file_io_pool,
681
0
           filename_iterator,
682
0
           file_io_handle,
683
0
           bfio_access_flags,
684
0
           error ) != 1 )
685
0
      {
686
0
        libcerror_error_set(
687
0
         error,
688
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
689
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
690
0
         "%s: unable to set file IO handle: %d in pool.",
691
0
         function,
692
0
         filename_iterator );
693
694
0
        goto on_error;
695
0
      }
696
0
      file_io_handle = NULL;
697
0
    }
698
0
  }
699
  /* Open for write only
700
   */
701
0
  else if( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) != 0 )
702
0
  {
703
    /* Set the basename
704
     */
705
0
    filename_length = narrow_string_length(
706
0
           filenames[ 0 ] );
707
708
0
    if( filename_length == 0 )
709
0
    {
710
0
      libcerror_error_set(
711
0
       error,
712
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
713
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
714
0
       "%s: missing basename.",
715
0
       function );
716
717
0
      goto on_error;
718
0
    }
719
0
    if( libsmraw_io_handle_set_basename(
720
0
         internal_handle->io_handle,
721
0
         filenames[ 0 ],
722
0
         filename_length,
723
0
         error ) != 1 )
724
0
    {
725
0
      libcerror_error_set(
726
0
       error,
727
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
728
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
729
0
       "%s: unable to set basename.",
730
0
      function );
731
732
0
      goto on_error;
733
0
    }
734
    /* Initialize the file IO pool
735
     */
736
0
    if( libbfio_pool_initialize(
737
0
         &file_io_pool,
738
0
         0,
739
0
         internal_handle->maximum_number_of_open_handles,
740
0
         error ) != 1 )
741
0
    {
742
0
      libcerror_error_set(
743
0
       error,
744
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
745
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
746
0
       "%s: unable to create file IO pool.",
747
0
       function );
748
749
0
      goto on_error;
750
0
    }
751
0
  }
752
0
  if( libsmraw_handle_open_file_io_pool(
753
0
       handle,
754
0
       file_io_pool,
755
0
       access_flags,
756
0
       error ) != 1 )
757
0
  {
758
0
    libcerror_error_set(
759
0
     error,
760
0
     LIBCERROR_ERROR_DOMAIN_IO,
761
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
762
0
     "%s: unable to open handle using file IO pool.",
763
0
     function );
764
765
0
    goto on_error;
766
0
  }
767
0
  file_io_pool = NULL;
768
769
  /* Open the information file
770
   */
771
0
  if( internal_handle->io_handle->basename != NULL )
772
0
  {
773
0
    information_filename_length = internal_handle->io_handle->basename_size + 9;
774
775
0
    information_filename = system_string_allocate(
776
0
                            information_filename_length + 1 );
777
778
0
    if( information_filename == NULL )
779
0
    {
780
0
      libcerror_error_set(
781
0
       error,
782
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
783
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
784
0
       "%s: unable to create information filename.",
785
0
       function );
786
787
0
      goto on_error;
788
0
    }
789
0
    if( system_string_copy(
790
0
         information_filename,
791
0
         internal_handle->io_handle->basename,
792
0
         internal_handle->io_handle->basename_size - 1 ) == NULL )
793
0
    {
794
0
      libcerror_error_set(
795
0
       error,
796
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
797
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
798
0
       "%s: unable to copy basename to information filename.",
799
0
       function );
800
801
0
      goto on_error;
802
0
    }
803
0
    filename_index = internal_handle->io_handle->basename_size - 1;
804
805
0
    if( system_string_copy(
806
0
         &( information_filename[ filename_index ] ),
807
0
         _SYSTEM_STRING( ".raw.info" ),
808
0
         9 ) == NULL )
809
0
    {
810
0
      libcerror_error_set(
811
0
       error,
812
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
813
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
814
0
       "%s: unable to copy extension to information filename.",
815
0
       function );
816
817
0
      goto on_error;
818
0
    }
819
0
    filename_index += 9;
820
821
0
    information_filename[ filename_index ] = 0;
822
823
0
    if( libsmraw_information_file_initialize(
824
0
         &( internal_handle->information_file ),
825
0
         error ) != 1 )
826
0
    {
827
0
      libcerror_error_set(
828
0
       error,
829
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
830
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
831
0
       "%s: unable to create information file.",
832
0
       function );
833
834
0
      goto on_error;
835
0
    }
836
0
    information_filename_length = system_string_length(
837
0
                                   information_filename );
838
839
0
    if( libsmraw_information_file_set_name(
840
0
         internal_handle->information_file,
841
0
         information_filename,
842
0
         information_filename_length,
843
0
         error ) != 1 )
844
0
    {
845
0
      libcerror_error_set(
846
0
       error,
847
0
       LIBCERROR_ERROR_DOMAIN_IO,
848
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
849
0
       "%s: unable to set information filename.",
850
0
       function );
851
852
0
      goto on_error;
853
0
    }
854
0
    if( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) != 0 )
855
0
    {
856
0
      if( libsmraw_handle_read_information_file(
857
0
           internal_handle,
858
0
           error ) != 1 )
859
0
      {
860
0
        libcerror_error_set(
861
0
         error,
862
0
         LIBCERROR_ERROR_DOMAIN_IO,
863
0
         LIBCERROR_IO_ERROR_READ_FAILED,
864
0
         "%s: unable to read information file.",
865
0
         function );
866
867
0
        goto on_error;
868
0
      }
869
0
    }
870
0
    memory_free(
871
0
     information_filename );
872
873
0
    information_filename = NULL;
874
875
0
    if( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) != 0 )
876
0
    {
877
0
      internal_handle->write_information_on_close = 1;
878
0
    }
879
0
  }
880
0
  internal_handle->file_io_pool_created_in_library = 1;
881
882
0
  return( 1 );
883
884
0
on_error:
885
0
  if( information_filename != NULL )
886
0
  {
887
0
    memory_free(
888
0
     information_filename );
889
0
  }
890
0
  if( file_io_handle != NULL )
891
0
  {
892
0
    libbfio_handle_free(
893
0
     &file_io_handle,
894
0
     NULL );
895
0
  }
896
0
  if( file_io_pool != NULL )
897
0
  {
898
0
    libbfio_pool_free(
899
0
     &file_io_pool,
900
0
     NULL );
901
0
  }
902
0
  if( internal_handle->information_file != NULL )
903
0
  {
904
0
    libsmraw_information_file_initialize(
905
0
     &( internal_handle->information_file ),
906
0
     NULL );
907
0
  }
908
0
  if( internal_handle->file_io_pool != NULL )
909
0
  {
910
0
    libbfio_pool_free(
911
0
     &( internal_handle->file_io_pool ),
912
0
     NULL );
913
0
  }
914
0
  libsmraw_io_handle_clear(
915
0
   internal_handle->io_handle,
916
0
   NULL );
917
918
0
  return( -1 );
919
0
}
920
921
#if defined( HAVE_WIDE_CHARACTER_TYPE )
922
923
/* Opens a set of storage media RAW files
924
 * Returns 1 if successful or -1 on error
925
 */
926
int libsmraw_handle_open_wide(
927
     libsmraw_handle_t *handle,
928
     wchar_t * const filenames[],
929
     int number_of_filenames,
930
     int access_flags,
931
     libcerror_error_t **error )
932
{
933
  libbfio_handle_t *file_io_handle            = NULL;
934
  libbfio_pool_t *file_io_pool                = NULL;
935
  libsmraw_internal_handle_t *internal_handle = NULL;
936
  system_character_t *information_filename    = NULL;
937
  static char *function                       = "libsmraw_handle_open_wide";
938
  size_t filename_index                       = 0;
939
  size_t filename_length                      = 0;
940
  size_t information_filename_length          = 0;
941
  int bfio_access_flags                       = 0;
942
  int filename_iterator                       = 0;
943
944
  if( handle == NULL )
945
  {
946
    libcerror_error_set(
947
     error,
948
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
949
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
950
     "%s: invalid handle.",
951
     function );
952
953
    return( -1 );
954
  }
955
  internal_handle = (libsmraw_internal_handle_t *) handle;
956
957
  if( internal_handle->io_handle == NULL )
958
  {
959
    libcerror_error_set(
960
     error,
961
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
962
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
963
     "%s: invalid handle - missing IO handle.",
964
     function );
965
966
    return( -1 );
967
  }
968
  if( internal_handle->file_io_pool != NULL )
969
  {
970
    libcerror_error_set(
971
     error,
972
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
973
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
974
     "%s: invalid handle - file IO pool value already set.",
975
     function );
976
977
    return( -1 );
978
  }
979
  if( internal_handle->information_file != NULL )
980
  {
981
    libcerror_error_set(
982
     error,
983
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
984
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
985
     "%s: invalid handle - information file value already set.",
986
     function );
987
988
    return( -1 );
989
  }
990
  if( filenames == NULL )
991
  {
992
    libcerror_error_set(
993
     error,
994
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
995
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
996
     "%s: invalid filenames.",
997
     function );
998
999
    return( -1 );
1000
  }
1001
  if( number_of_filenames <= 0 )
1002
  {
1003
    libcerror_error_set(
1004
     error,
1005
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1006
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1007
     "%s: invalid number of filenames value out of bounds.",
1008
     function );
1009
1010
    return( -1 );
1011
  }
1012
  if( ( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) == 0 )
1013
   && ( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) == 0 ) )
1014
  {
1015
    libcerror_error_set(
1016
     error,
1017
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1018
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1019
     "%s: unsupported access flags.",
1020
     function );
1021
1022
    return( -1 );
1023
  }
1024
  /* Open for read only or read/write
1025
   */
1026
  if( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) != 0 )
1027
  {
1028
    if( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) != 0 )
1029
    {
1030
      bfio_access_flags |= LIBBFIO_ACCESS_FLAG_READ;
1031
    }
1032
    if( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) != 0 )
1033
    {
1034
      bfio_access_flags |= LIBBFIO_ACCESS_FLAG_WRITE;
1035
    }
1036
    /* Set the basename
1037
     */
1038
    filename_length = wide_string_length(
1039
           filenames[ 0 ] );
1040
1041
    if( filename_length <= 4 )
1042
    {
1043
      libcerror_error_set(
1044
       error,
1045
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1046
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1047
       "%s: missing basename.",
1048
       function );
1049
1050
      goto on_error;
1051
    }
1052
    if( libsmraw_io_handle_set_basename_wide(
1053
         internal_handle->io_handle,
1054
         filenames[ 0 ],
1055
         filename_length - 4,
1056
         error ) != 1 )
1057
    {
1058
      libcerror_error_set(
1059
       error,
1060
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1061
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1062
       "%s: unable to set basename.",
1063
      function );
1064
1065
      goto on_error;
1066
    }
1067
    if( libbfio_pool_initialize(
1068
         &file_io_pool,
1069
         number_of_filenames,
1070
         internal_handle->maximum_number_of_open_handles,
1071
         error ) != 1 )
1072
    {
1073
      libcerror_error_set(
1074
       error,
1075
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1076
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1077
       "%s: unable to create file IO pool.",
1078
       function );
1079
1080
      goto on_error;
1081
    }
1082
    for( filename_iterator = 0;
1083
         filename_iterator < number_of_filenames;
1084
         filename_iterator++ )
1085
    {
1086
      filename_length = wide_string_length(
1087
             filenames[ filename_iterator ] );
1088
1089
      if( filename_length == 0 )
1090
      {
1091
        libcerror_error_set(
1092
         error,
1093
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1094
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1095
         "%s: missing filename: %d.",
1096
         function,
1097
         filename_iterator );
1098
1099
        goto on_error;
1100
      }
1101
      if( libbfio_file_initialize(
1102
           &file_io_handle,
1103
           error ) != 1 )
1104
      {
1105
        libcerror_error_set(
1106
         error,
1107
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1108
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1109
         "%s: unable to create file IO handle: %d.",
1110
         function,
1111
         filename_iterator );
1112
1113
        goto on_error;
1114
      }
1115
#if defined( HAVE_DEBUG_OUTPUT )
1116
      if( libbfio_handle_set_track_offsets_read(
1117
           file_io_handle,
1118
           1,
1119
           error ) != 1 )
1120
      {
1121
                    libcerror_error_set(
1122
                     error,
1123
                     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1124
                     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1125
                     "%s: unable to set track offsets read in file IO handle: %d.",
1126
                     function,
1127
         filename_iterator );
1128
1129
                    goto on_error;
1130
      }
1131
#endif
1132
      if( libbfio_file_set_name_wide(
1133
           file_io_handle,
1134
           filenames[ filename_iterator ],
1135
           filename_length + 1,
1136
           error ) != 1 )
1137
      {
1138
        libcerror_error_set(
1139
         error,
1140
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1141
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1142
         "%s: unable to set name in file IO handle: %d.",
1143
         function,
1144
         filename_iterator );
1145
1146
        goto on_error;
1147
      }
1148
      if( libbfio_pool_set_handle(
1149
           file_io_pool,
1150
           filename_iterator,
1151
           file_io_handle,
1152
           bfio_access_flags,
1153
           error ) != 1 )
1154
      {
1155
        libcerror_error_set(
1156
         error,
1157
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1158
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1159
         "%s: unable to set file IO handle: %d in pool.",
1160
         function,
1161
         filename_iterator );
1162
1163
        goto on_error;
1164
      }
1165
      file_io_handle = NULL;
1166
    }
1167
  }
1168
  /* Open for write only
1169
   */
1170
  else if( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) != 0 )
1171
  {
1172
    /* Set the basename
1173
     */
1174
    filename_length = wide_string_length(
1175
           filenames[ 0 ] );
1176
1177
    if( filename_length == 0 )
1178
    {
1179
      libcerror_error_set(
1180
       error,
1181
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1182
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1183
       "%s: missing basename.",
1184
       function );
1185
1186
      goto on_error;
1187
    }
1188
    if( libsmraw_io_handle_set_basename_wide(
1189
         internal_handle->io_handle,
1190
         filenames[ 0 ],
1191
         filename_length,
1192
         error ) != 1 )
1193
    {
1194
      libcerror_error_set(
1195
       error,
1196
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1197
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1198
       "%s: unable to set basename.",
1199
      function );
1200
1201
      goto on_error;
1202
    }
1203
    /* Initialize the file IO pool
1204
     */
1205
    if( libbfio_pool_initialize(
1206
         &file_io_pool,
1207
         0,
1208
         internal_handle->maximum_number_of_open_handles,
1209
         error ) != 1 )
1210
    {
1211
      libcerror_error_set(
1212
       error,
1213
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1214
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1215
       "%s: unable to create file IO pool.",
1216
       function );
1217
1218
      goto on_error;
1219
    }
1220
  }
1221
  if( libsmraw_handle_open_file_io_pool(
1222
       handle,
1223
       file_io_pool,
1224
       access_flags,
1225
       error ) != 1 )
1226
  {
1227
    libcerror_error_set(
1228
     error,
1229
     LIBCERROR_ERROR_DOMAIN_IO,
1230
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1231
     "%s: unable to open handle using file IO pool.",
1232
     function );
1233
1234
    goto on_error;
1235
  }
1236
  file_io_pool = NULL;
1237
1238
  /* Open the information file
1239
   */
1240
  if( internal_handle->io_handle->basename != NULL )
1241
  {
1242
    information_filename_length = internal_handle->io_handle->basename_size + 9;
1243
1244
    information_filename = system_string_allocate(
1245
                            information_filename_length + 1 );
1246
1247
    if( information_filename == NULL )
1248
    {
1249
      libcerror_error_set(
1250
       error,
1251
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1252
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1253
       "%s: unable to create information filename.",
1254
       function );
1255
1256
      goto on_error;
1257
    }
1258
    if( system_string_copy(
1259
         information_filename,
1260
         internal_handle->io_handle->basename,
1261
         internal_handle->io_handle->basename_size - 1 ) == NULL )
1262
    {
1263
      libcerror_error_set(
1264
       error,
1265
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1266
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1267
       "%s: unable to copy basename to information filename.",
1268
       function );
1269
1270
      goto on_error;
1271
    }
1272
    filename_index = internal_handle->io_handle->basename_size - 1;
1273
1274
    if( system_string_copy(
1275
         &( information_filename[ filename_index ] ),
1276
         _SYSTEM_STRING( ".raw.info" ),
1277
         9 ) == NULL )
1278
    {
1279
      libcerror_error_set(
1280
       error,
1281
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1282
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1283
       "%s: unable to copy extension to information filename.",
1284
       function );
1285
1286
      goto on_error;
1287
    }
1288
    filename_index += 9;
1289
1290
    information_filename[ filename_index ] = 0;
1291
1292
    if( libsmraw_information_file_initialize(
1293
         &( internal_handle->information_file ),
1294
         error ) != 1 )
1295
    {
1296
      libcerror_error_set(
1297
       error,
1298
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1299
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1300
       "%s: unable to create information file.",
1301
       function );
1302
1303
      goto on_error;
1304
    }
1305
    information_filename_length = system_string_length(
1306
                                   information_filename );
1307
1308
    if( libsmraw_information_file_set_name(
1309
         internal_handle->information_file,
1310
         information_filename,
1311
         information_filename_length,
1312
         error ) != 1 )
1313
    {
1314
      libcerror_error_set(
1315
       error,
1316
       LIBCERROR_ERROR_DOMAIN_IO,
1317
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1318
       "%s: unable to set information filename.",
1319
       function );
1320
1321
      goto on_error;
1322
    }
1323
    if( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) != 0 )
1324
    {
1325
      if( libsmraw_handle_read_information_file(
1326
           internal_handle,
1327
           error ) != 1 )
1328
      {
1329
        libcerror_error_set(
1330
         error,
1331
         LIBCERROR_ERROR_DOMAIN_IO,
1332
         LIBCERROR_IO_ERROR_READ_FAILED,
1333
         "%s: unable to read information file.",
1334
         function );
1335
1336
        goto on_error;
1337
      }
1338
    }
1339
    memory_free(
1340
     information_filename );
1341
1342
    information_filename = NULL;
1343
1344
    if( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) != 0 )
1345
    {
1346
      internal_handle->write_information_on_close = 1;
1347
    }
1348
  }
1349
  internal_handle->file_io_pool_created_in_library = 1;
1350
1351
  return( 1 );
1352
1353
on_error:
1354
  if( information_filename != NULL )
1355
  {
1356
    memory_free(
1357
     information_filename );
1358
  }
1359
  if( file_io_handle != NULL )
1360
  {
1361
    libbfio_handle_free(
1362
     &file_io_handle,
1363
     NULL );
1364
  }
1365
  if( file_io_pool != NULL )
1366
  {
1367
    libbfio_pool_free(
1368
     &file_io_pool,
1369
     NULL );
1370
  }
1371
  if( internal_handle->information_file != NULL )
1372
  {
1373
    libsmraw_information_file_initialize(
1374
     &( internal_handle->information_file ),
1375
     NULL );
1376
  }
1377
  if( internal_handle->file_io_pool != NULL )
1378
  {
1379
    libbfio_pool_free(
1380
     &( internal_handle->file_io_pool ),
1381
     NULL );
1382
  }
1383
  libsmraw_io_handle_clear(
1384
   internal_handle->io_handle,
1385
   NULL );
1386
1387
  return( -1 );
1388
}
1389
1390
#endif
1391
1392
/* Opens a set of storage media RAW files using a Basic File IO (bfio) pool
1393
 * Returns 1 if successful or -1 on error
1394
 */
1395
int libsmraw_handle_open_file_io_pool(
1396
     libsmraw_handle_t *handle,
1397
     libbfio_pool_t *file_io_pool,
1398
     int access_flags,
1399
     libcerror_error_t **error )
1400
22
{
1401
22
  libbfio_handle_t *file_io_handle            = NULL;
1402
22
  libsmraw_internal_handle_t *internal_handle = NULL;
1403
22
  static char *function                       = "libsmraw_handle_open_file_io_pool";
1404
22
  size64_t file_io_handle_size                = 0;
1405
22
  int number_of_file_io_handles               = 0;
1406
22
  int bfio_access_flags                       = 0;
1407
22
  int file_io_handle_index                    = 0;
1408
22
  int file_io_handle_is_open                  = 0;
1409
1410
22
  if( handle == NULL )
1411
0
  {
1412
0
    libcerror_error_set(
1413
0
     error,
1414
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1415
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1416
0
     "%s: invalid handle.",
1417
0
     function );
1418
1419
0
    return( -1 );
1420
0
  }
1421
22
  internal_handle = (libsmraw_internal_handle_t *) handle;
1422
1423
22
  if( internal_handle->io_handle == NULL )
1424
0
  {
1425
0
    libcerror_error_set(
1426
0
     error,
1427
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1428
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1429
0
     "%s: invalid handle - missing IO handle.",
1430
0
     function );
1431
1432
0
    return( -1 );
1433
0
  }
1434
22
  if( internal_handle->file_io_pool != NULL )
1435
0
  {
1436
0
    libcerror_error_set(
1437
0
     error,
1438
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1439
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1440
0
     "%s: invalid handle - file IO pool value already set.",
1441
0
     function );
1442
1443
0
    return( -1 );
1444
0
  }
1445
22
  if( file_io_pool == NULL )
1446
0
  {
1447
0
    libcerror_error_set(
1448
0
     error,
1449
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1450
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1451
0
     "%s: invalid file IO pool.",
1452
0
     function );
1453
1454
0
    return( -1 );
1455
0
  }
1456
22
  if( ( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) == 0 )
1457
22
   && ( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) == 0 ) )
1458
0
  {
1459
0
    libcerror_error_set(
1460
0
     error,
1461
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1462
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1463
0
     "%s: unsupported access flags.",
1464
0
     function );
1465
1466
0
    return( -1 );
1467
0
  }
1468
22
  if( libbfio_pool_get_number_of_handles(
1469
22
       file_io_pool,
1470
22
       &number_of_file_io_handles,
1471
22
       error ) != 1 )
1472
0
  {
1473
0
    libcerror_error_set(
1474
0
     error,
1475
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1476
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1477
0
     "%s: unable to retrieve the number of handles in the file IO pool.",
1478
0
     function );
1479
1480
0
    goto on_error;
1481
0
  }
1482
22
  if( libfdata_stream_initialize(
1483
22
       &( internal_handle->segments_stream ),
1484
22
       (intptr_t *) internal_handle->io_handle,
1485
22
       NULL,
1486
22
       NULL,
1487
22
       (int (*)(intptr_t *, intptr_t *, int, int *, off64_t *, size64_t *, uint32_t *, libcerror_error_t **)) &libsmraw_io_handle_create_segment,
1488
22
       (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libsmraw_io_handle_read_segment_data,
1489
22
       (ssize_t (*)(intptr_t *, intptr_t *, int, int, const uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libsmraw_io_handle_write_segment_data,
1490
22
       (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libsmraw_io_handle_seek_segment_offset,
1491
22
       LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
1492
22
       error ) != 1 )
1493
0
  {
1494
0
    libcerror_error_set(
1495
0
     error,
1496
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1497
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1498
0
     "%s: unable to create segments stream.",
1499
0
     function );
1500
1501
0
    goto on_error;
1502
0
  }
1503
22
  if( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) != 0 )
1504
22
  {
1505
22
    if( number_of_file_io_handles <= 0 )
1506
0
    {
1507
0
      libcerror_error_set(
1508
0
       error,
1509
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1510
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1511
0
       "%s: missing file IO handles.",
1512
0
       function );
1513
1514
0
      goto on_error;
1515
0
    }
1516
22
    if( libfdata_stream_resize(
1517
22
         internal_handle->segments_stream,
1518
22
         number_of_file_io_handles,
1519
22
         error ) != 1 )
1520
0
    {
1521
0
      libcerror_error_set(
1522
0
       error,
1523
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1524
0
       LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
1525
0
       "%s: unable to resize segments stream.",
1526
0
       function );
1527
1528
0
      goto on_error;
1529
0
    }
1530
22
    if( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) != 0 )
1531
0
    {
1532
0
      bfio_access_flags = LIBBFIO_OPEN_READ_WRITE;
1533
0
    }
1534
22
    else
1535
22
    {
1536
22
      bfio_access_flags = LIBBFIO_OPEN_READ;
1537
22
    }
1538
22
    for( file_io_handle_index = 0;
1539
44
         file_io_handle_index < number_of_file_io_handles;
1540
22
         file_io_handle_index++ )
1541
22
    {
1542
22
      if( libbfio_pool_get_handle(
1543
22
           file_io_pool,
1544
22
           file_io_handle_index,
1545
22
           &file_io_handle,
1546
22
           error ) != 1 )
1547
0
      {
1548
0
        libcerror_error_set(
1549
0
         error,
1550
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1551
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1552
0
         "%s: unable to retrieve file IO handle from pool entry: %d.",
1553
0
         function,
1554
0
         file_io_handle_index );
1555
1556
0
        goto on_error;
1557
0
      }
1558
#if defined( HAVE_DEBUG_OUTPUT )
1559
      if( libcnotify_verbose != 0 )
1560
      {
1561
        libcnotify_printf(
1562
         "%s: processing pool entry: %d.\n",
1563
         function,
1564
         file_io_handle_index );
1565
      }
1566
#endif
1567
22
      file_io_handle_is_open = libbfio_handle_is_open(
1568
22
                                file_io_handle,
1569
22
                                error );
1570
1571
22
      if( file_io_handle_is_open == -1 )
1572
0
      {
1573
0
        libcerror_error_set(
1574
0
         error,
1575
0
         LIBCERROR_ERROR_DOMAIN_IO,
1576
0
         LIBCERROR_IO_ERROR_OPEN_FAILED,
1577
0
         "%s: unable to determine if file IO handle is open.",
1578
0
         function );
1579
1580
0
        goto on_error;
1581
0
      }
1582
22
      else if( file_io_handle_is_open == 0 )
1583
22
      {
1584
22
        if( libbfio_pool_open(
1585
22
             file_io_pool,
1586
22
             file_io_handle_index,
1587
22
             bfio_access_flags,
1588
22
             error ) != 1 )
1589
0
        {
1590
0
          libcerror_error_set(
1591
0
           error,
1592
0
           LIBCERROR_ERROR_DOMAIN_IO,
1593
0
           LIBCERROR_IO_ERROR_OPEN_FAILED,
1594
0
           "%s: unable to open pool entry: %d.",
1595
0
           function,
1596
0
           file_io_handle_index );
1597
1598
0
          goto on_error;
1599
0
        }
1600
22
      }
1601
22
      if( libbfio_pool_get_size(
1602
22
           file_io_pool,
1603
22
           file_io_handle_index,
1604
22
           &file_io_handle_size,
1605
22
           error ) != 1 )
1606
0
      {
1607
0
        libcerror_error_set(
1608
0
         error,
1609
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1610
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1611
0
         "%s: unable to retrieve file size for pool entry: %d.",
1612
0
         function,
1613
0
         file_io_handle_index );
1614
1615
0
        goto on_error;
1616
0
      }
1617
22
      if( libfdata_stream_set_segment_by_index(
1618
22
           internal_handle->segments_stream,
1619
22
           file_io_handle_index,
1620
22
           file_io_handle_index,
1621
22
           0,
1622
22
           file_io_handle_size,
1623
22
           0,
1624
22
           error ) != 1 )
1625
0
      {
1626
0
        libcerror_error_set(
1627
0
         error,
1628
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1629
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1630
0
         "%s: unable to set segment: %d in segments stream.",
1631
0
         function,
1632
0
         file_io_handle_index );
1633
1634
0
        goto on_error;
1635
0
      }
1636
22
      if( file_io_handle_index == 0 )
1637
22
      {
1638
22
        internal_handle->io_handle->maximum_segment_size = file_io_handle_size;
1639
22
      }
1640
0
      else if( file_io_handle_size > internal_handle->io_handle->maximum_segment_size )
1641
0
      {
1642
0
        internal_handle->io_handle->maximum_segment_size = file_io_handle_size;
1643
0
      }
1644
22
    }
1645
22
    if( libfdata_stream_get_size(
1646
22
         internal_handle->segments_stream,
1647
22
         &( internal_handle->io_handle->media_size ),
1648
22
         error ) != 1 )
1649
0
    {
1650
0
      libcerror_error_set(
1651
0
       error,
1652
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1653
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1654
0
       "%s: unable to retrieve size from segments stream.",
1655
0
       function );
1656
1657
0
      goto on_error;
1658
0
    }
1659
22
    internal_handle->read_values_initialized = 1;
1660
22
  }
1661
22
  internal_handle->file_io_pool = file_io_pool;
1662
1663
22
  return( 1 );
1664
1665
0
on_error:
1666
0
  if( internal_handle->segments_stream != NULL )
1667
0
  {
1668
0
    libfdata_stream_free(
1669
0
     &( internal_handle->segments_stream ),
1670
0
     NULL );
1671
0
  }
1672
0
  internal_handle->read_values_initialized = 0;
1673
1674
0
  return( -1 );
1675
22
}
1676
1677
/* Read an information file using a Basic File IO (bfio) handle
1678
 * Returns 1 if successful or -1 on error
1679
 */
1680
int libsmraw_handle_read_information_file(
1681
     libsmraw_internal_handle_t *internal_handle,
1682
     libcerror_error_t **error )
1683
0
{
1684
0
  libbfio_handle_t *file_io_handle = NULL;
1685
0
  static char *function            = "libsmraw_handle_read_information_file";
1686
0
  int result                       = 0;
1687
1688
0
  if( internal_handle == NULL )
1689
0
  {
1690
0
    libcerror_error_set(
1691
0
     error,
1692
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1693
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1694
0
     "%s: invalid handle.",
1695
0
     function );
1696
1697
0
    return( -1 );
1698
0
  }
1699
0
  if( internal_handle->information_file == NULL )
1700
0
  {
1701
0
    libcerror_error_set(
1702
0
     error,
1703
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1704
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1705
0
     "%s: invalid handle - missing information file.",
1706
0
     function );
1707
1708
0
    return( -1 );
1709
0
  }
1710
0
  if( libbfio_file_initialize(
1711
0
       &file_io_handle,
1712
0
       error ) != 1 )
1713
0
  {
1714
0
    libcerror_error_set(
1715
0
     error,
1716
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1717
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1718
0
     "%s: unable to create file IO handle.",
1719
0
     function );
1720
1721
0
    return( -1 );
1722
0
  }
1723
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1724
  if( libbfio_file_set_name_wide(
1725
       file_io_handle,
1726
       internal_handle->information_file->name,
1727
       internal_handle->information_file->name_size - 1,
1728
       error ) != 1 )
1729
#else
1730
0
  if( libbfio_file_set_name(
1731
0
       file_io_handle,
1732
0
       internal_handle->information_file->name,
1733
0
       internal_handle->information_file->name_size - 1,
1734
0
       error ) != 1 )
1735
0
#endif
1736
0
  {
1737
0
    libcerror_error_set(
1738
0
     error,
1739
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1740
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1741
0
     "%s: unable to set name in file IO handle.",
1742
0
     function );
1743
1744
0
    goto on_error;
1745
0
  }
1746
0
  result = libbfio_handle_exists(
1747
0
      file_io_handle,
1748
0
      error );
1749
1750
0
  if( result == -1 )
1751
0
  {
1752
0
    libcerror_error_set(
1753
0
     error,
1754
0
     LIBCERROR_ERROR_DOMAIN_IO,
1755
0
     LIBCERROR_IO_ERROR_GENERIC,
1756
0
     "%s: unable to determine if information filename exists.",
1757
0
     function );
1758
1759
0
    goto on_error;
1760
0
  }
1761
0
  if( libbfio_handle_free(
1762
0
       &file_io_handle,
1763
0
       error ) != 1 )
1764
0
  {
1765
0
    libcerror_error_set(
1766
0
     error,
1767
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1768
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1769
0
     "%s: unable to free file IO handle.",
1770
0
     function );
1771
1772
0
    goto on_error;
1773
0
  }
1774
  /* Only read the information file if it exists
1775
   */
1776
0
  if( result == 1 )
1777
0
  {
1778
0
    if( libsmraw_information_file_open(
1779
0
         internal_handle->information_file,
1780
0
         internal_handle->information_file->name,
1781
0
         LIBSMRAW_OPEN_READ,
1782
0
         error ) != 1 )
1783
0
    {
1784
0
      libcerror_error_set(
1785
0
       error,
1786
0
       LIBCERROR_ERROR_DOMAIN_IO,
1787
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1788
0
       "%s: unable to open information file.",
1789
0
       function );
1790
1791
0
      goto on_error;
1792
0
    }
1793
0
    if( libsmraw_information_file_read_section(
1794
0
         internal_handle->information_file,
1795
0
         (uint8_t *) "media_values",
1796
0
         12,
1797
0
         internal_handle->media_values,
1798
0
         error ) == -1 )
1799
0
    {
1800
0
      libcerror_error_set(
1801
0
       error,
1802
0
       LIBCERROR_ERROR_DOMAIN_IO,
1803
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1804
0
       "%s: unable to read media values from information file.",
1805
0
       function );
1806
1807
0
      libsmraw_information_file_close(
1808
0
       internal_handle->information_file,
1809
0
       NULL );
1810
1811
0
      goto on_error;
1812
0
    }
1813
0
    if( libsmraw_information_file_read_section(
1814
0
         internal_handle->information_file,
1815
0
         (uint8_t *) "information_values",
1816
0
         18,
1817
0
         internal_handle->information_values,
1818
0
         error ) == -1 )
1819
0
    {
1820
0
      libcerror_error_set(
1821
0
       error,
1822
0
       LIBCERROR_ERROR_DOMAIN_IO,
1823
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1824
0
       "%s: unable to read information values from information file.",
1825
0
       function );
1826
1827
0
      libsmraw_information_file_close(
1828
0
       internal_handle->information_file,
1829
0
       NULL );
1830
1831
0
      goto on_error;
1832
0
    }
1833
0
    if( libsmraw_information_file_read_section(
1834
0
         internal_handle->information_file,
1835
0
         (uint8_t *) "integrity_hash_values",
1836
0
         21,
1837
0
         internal_handle->integrity_hash_values,
1838
0
         error ) == -1 )
1839
0
    {
1840
0
      libcerror_error_set(
1841
0
       error,
1842
0
       LIBCERROR_ERROR_DOMAIN_IO,
1843
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1844
0
       "%s: unable to read integrity hash values from information file.",
1845
0
       function );
1846
1847
0
      libsmraw_information_file_close(
1848
0
       internal_handle->information_file,
1849
0
       NULL );
1850
1851
0
      goto on_error;
1852
0
    }
1853
0
    if( libsmraw_information_file_close(
1854
0
         internal_handle->information_file,
1855
0
         error ) != 0 )
1856
0
    {
1857
0
      libcerror_error_set(
1858
0
       error,
1859
0
       LIBCERROR_ERROR_DOMAIN_IO,
1860
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1861
0
       "%s: unable to close information file.",
1862
0
       function );
1863
1864
0
      goto on_error;
1865
0
    }
1866
0
  }
1867
0
  return( 1 );
1868
1869
0
on_error:
1870
0
  if( file_io_handle != NULL )
1871
0
  {
1872
0
    libbfio_handle_free(
1873
0
     &file_io_handle,
1874
0
     NULL );
1875
0
  }
1876
0
  return( -1 );
1877
0
}
1878
1879
/* Closes a RAW handle
1880
 * Returns the 0 if succesful or -1 on error
1881
 */
1882
int libsmraw_handle_close(
1883
     libsmraw_handle_t *handle,
1884
     libcerror_error_t **error )
1885
22
{
1886
22
  libsmraw_internal_handle_t *internal_handle = NULL;
1887
22
  static char *function                       = "libsmraw_handle_close";
1888
22
  int result                                  = 0;
1889
1890
22
  if( handle == NULL )
1891
0
  {
1892
0
    libcerror_error_set(
1893
0
     error,
1894
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1895
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1896
0
     "%s: invalid handle.",
1897
0
     function );
1898
1899
0
    return( -1 );
1900
0
  }
1901
22
  internal_handle = (libsmraw_internal_handle_t *) handle;
1902
1903
22
  if( internal_handle->file_io_pool == NULL )
1904
0
  {
1905
0
    libcerror_error_set(
1906
0
     error,
1907
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1908
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1909
0
     "%s: invalid handle - missing file IO pool.",
1910
0
     function );
1911
1912
0
    return( -1 );
1913
0
  }
1914
22
  if( internal_handle->write_information_on_close != 0 )
1915
0
  {
1916
0
    if( libsmraw_information_file_open(
1917
0
         internal_handle->information_file,
1918
0
         internal_handle->information_file->name,
1919
0
         LIBSMRAW_OPEN_WRITE,
1920
0
         error ) != 1 )
1921
0
    {
1922
0
      libcerror_error_set(
1923
0
       error,
1924
0
       LIBCERROR_ERROR_DOMAIN_IO,
1925
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1926
0
       "%s: unable to open information file.",
1927
0
       function );
1928
1929
0
      return( -1 );
1930
0
    }
1931
0
    if( libsmraw_information_file_write_section(
1932
0
         internal_handle->information_file,
1933
0
         (uint8_t *) "information_values",
1934
0
         18,
1935
0
         internal_handle->information_values,
1936
0
         error ) != 1 )
1937
0
    {
1938
0
      libcerror_error_set(
1939
0
       error,
1940
0
       LIBCERROR_ERROR_DOMAIN_IO,
1941
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
1942
0
       "%s: unable to write information values to information file.",
1943
0
       function );
1944
1945
0
      return( -1 );
1946
0
    }
1947
0
    if( libsmraw_information_file_write_section(
1948
0
         internal_handle->information_file,
1949
0
         (uint8_t *) "integrity_hash_values",
1950
0
         21,
1951
0
         internal_handle->integrity_hash_values,
1952
0
         error ) != 1 )
1953
0
    {
1954
0
      libcerror_error_set(
1955
0
       error,
1956
0
       LIBCERROR_ERROR_DOMAIN_IO,
1957
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
1958
0
       "%s: unable to write integrity hash values to information file.",
1959
0
       function );
1960
1961
0
      return( -1 );
1962
0
    }
1963
0
    if( libsmraw_information_file_close(
1964
0
         internal_handle->information_file,
1965
0
         error ) != 0 )
1966
0
    {
1967
0
      libcerror_error_set(
1968
0
       error,
1969
0
       LIBCERROR_ERROR_DOMAIN_IO,
1970
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
1971
0
       "%s: unable to close information file.",
1972
0
       function );
1973
1974
0
      result = -1;
1975
0
    }
1976
0
  }
1977
22
  if( internal_handle->file_io_pool_created_in_library != 0 )
1978
0
  {
1979
0
    if( libbfio_pool_close_all(
1980
0
         internal_handle->file_io_pool,
1981
0
         error ) != 0 )
1982
0
    {
1983
0
      libcerror_error_set(
1984
0
       error,
1985
0
       LIBCERROR_ERROR_DOMAIN_IO,
1986
0
       LIBCERROR_IO_ERROR_GENERIC,
1987
0
       "%s: unable close file IO pool.",
1988
0
       function );
1989
1990
0
      result = -1;
1991
0
    }
1992
0
    if( libbfio_pool_free(
1993
0
         &( internal_handle->file_io_pool ),
1994
0
         error ) != 1 )
1995
0
    {
1996
0
      libcerror_error_set(
1997
0
       error,
1998
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1999
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2000
0
       "%s: unable to free file IO pool.",
2001
0
       function );
2002
2003
0
      result = -1;
2004
0
    }
2005
0
    internal_handle->file_io_pool_created_in_library = 0;
2006
0
  }
2007
22
  internal_handle->file_io_pool             = NULL;
2008
22
  internal_handle->read_values_initialized  = 0;
2009
22
  internal_handle->write_values_initialized = 0;
2010
2011
22
  if( libsmraw_io_handle_clear(
2012
22
       internal_handle->io_handle,
2013
22
       error ) != 1 )
2014
0
  {
2015
0
    libcerror_error_set(
2016
0
     error,
2017
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2018
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2019
0
     "%s: unable to clear IO handle.",
2020
0
     function );
2021
2022
0
    result = -1;
2023
0
  }
2024
22
  if( libfdata_stream_free(
2025
22
       &( internal_handle->segments_stream ),
2026
22
       error ) != 1 )
2027
0
  {
2028
0
    libcerror_error_set(
2029
0
     error,
2030
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2031
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2032
0
     "%s: unable to free segments stream.",
2033
0
     function );
2034
2035
0
    result = -1;
2036
0
  }
2037
22
  if( internal_handle->information_file != NULL )
2038
0
  {
2039
0
    if( libsmraw_information_file_free(
2040
0
         &( internal_handle->information_file ),
2041
0
         error ) != 1 )
2042
0
    {
2043
0
      libcerror_error_set(
2044
0
       error,
2045
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2046
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2047
0
       "%s: unable to free information file.",
2048
0
       function );
2049
2050
0
      result = -1;
2051
0
    }
2052
0
  }
2053
22
  return( result );
2054
22
}
2055
2056
/* Reads a buffer
2057
 * Returns the number of bytes read or -1 on error
2058
 */
2059
ssize_t libsmraw_handle_read_buffer(
2060
         libsmraw_handle_t *handle,
2061
         void *buffer,
2062
         size_t buffer_size,
2063
         libcerror_error_t **error )
2064
0
{
2065
0
  libsmraw_internal_handle_t *internal_handle = NULL;
2066
0
  static char *function                       = "libsmraw_handle_read_buffer";
2067
0
  off64_t current_offset                      = 0;
2068
0
  ssize_t read_count                          = 0;
2069
2070
0
  if( handle == NULL )
2071
0
  {
2072
0
    libcerror_error_set(
2073
0
     error,
2074
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2075
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2076
0
     "%s: invalid handle.",
2077
0
     function );
2078
2079
0
    return( -1 );
2080
0
  }
2081
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
2082
2083
0
  if( internal_handle->io_handle == NULL )
2084
0
  {
2085
0
    libcerror_error_set(
2086
0
     error,
2087
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2088
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2089
0
     "%s: invalid handle - missing IO handle.",
2090
0
     function );
2091
2092
0
    return( -1 );
2093
0
  }
2094
0
  if( internal_handle->file_io_pool == NULL )
2095
0
  {
2096
0
    libcerror_error_set(
2097
0
     error,
2098
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2099
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2100
0
     "%s: invalid handle - missing file IO pool.",
2101
0
     function );
2102
2103
0
    return( -1 );
2104
0
  }
2105
0
  if( buffer == NULL )
2106
0
  {
2107
0
    libcerror_error_set(
2108
0
     error,
2109
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2110
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2111
0
     "%s: invalid buffer.",
2112
0
     function );
2113
2114
0
    return( -1 );
2115
0
  }
2116
0
  if( buffer_size > (size_t) SSIZE_MAX )
2117
0
  {
2118
0
    libcerror_error_set(
2119
0
     error,
2120
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2121
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2122
0
     "%s: invalid buffer size value exceeds maximum.",
2123
0
     function );
2124
2125
0
    return( -1 );
2126
0
  }
2127
0
  if( internal_handle->io_handle->media_size == 0 )
2128
0
  {
2129
0
    return( 0 );
2130
0
  }
2131
0
#if defined( HAVE_LIBSMRAW_MULTI_THREAD_SUPPORT )
2132
0
  if( libcthreads_read_write_lock_grab_for_write(
2133
0
       internal_handle->read_write_lock,
2134
0
       error ) != 1 )
2135
0
  {
2136
0
    libcerror_error_set(
2137
0
     error,
2138
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2139
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2140
0
     "%s: unable to grab read/write lock for writing.",
2141
0
     function );
2142
2143
0
    return( -1 );
2144
0
  }
2145
0
#endif
2146
0
  if( libfdata_stream_get_offset(
2147
0
       internal_handle->segments_stream,
2148
0
       &current_offset,
2149
0
       error ) != 1 )
2150
0
  {
2151
0
    libcerror_error_set(
2152
0
     error,
2153
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2154
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2155
0
     "%s: unable to retrieve current offset from segments stream.",
2156
0
     function );
2157
2158
0
    goto on_error;
2159
0
  }
2160
0
  if( current_offset < 0 )
2161
0
  {
2162
0
    libcerror_error_set(
2163
0
     error,
2164
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2165
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2166
0
     "%s: invalid current offset value out of bounds.",
2167
0
     function );
2168
2169
0
    goto on_error;
2170
0
  }
2171
  /* Bail out early for requests to read beyond the media size
2172
   */
2173
0
  if( (size64_t) current_offset >= internal_handle->io_handle->media_size )
2174
0
  {
2175
0
    buffer_size = 0;
2176
0
  }
2177
0
  else if( ( (size64_t) current_offset + buffer_size ) >= internal_handle->io_handle->media_size )
2178
0
  {
2179
0
    buffer_size = (size_t) ( internal_handle->io_handle->media_size - (size64_t) current_offset );
2180
0
  }
2181
0
  if( buffer_size > 0 )
2182
0
  {
2183
0
    read_count = libfdata_stream_read_buffer(
2184
0
                  internal_handle->segments_stream,
2185
0
                  (intptr_t *) internal_handle->file_io_pool,
2186
0
                  (uint8_t *) buffer,
2187
0
                  buffer_size,
2188
0
                  0,
2189
0
                  error );
2190
2191
0
    if( read_count < 0 )
2192
0
    {
2193
0
      libcerror_error_set(
2194
0
       error,
2195
0
       LIBCERROR_ERROR_DOMAIN_IO,
2196
0
       LIBCERROR_IO_ERROR_READ_FAILED,
2197
0
       "%s: unable to read buffer from segments stream.",
2198
0
       function );
2199
2200
0
      goto on_error;
2201
0
    }
2202
0
  }
2203
0
#if defined( HAVE_LIBSMRAW_MULTI_THREAD_SUPPORT )
2204
0
  if( libcthreads_read_write_lock_release_for_write(
2205
0
       internal_handle->read_write_lock,
2206
0
       error ) != 1 )
2207
0
  {
2208
0
    libcerror_error_set(
2209
0
     error,
2210
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2211
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2212
0
     "%s: unable to release read/write lock for writing.",
2213
0
     function );
2214
2215
0
    return( -1 );
2216
0
  }
2217
0
#endif
2218
0
  return( read_count );
2219
2220
0
on_error:
2221
0
#if defined( HAVE_LIBSMRAW_MULTI_THREAD_SUPPORT )
2222
0
  libcthreads_read_write_lock_release_for_write(
2223
0
    internal_handle->read_write_lock,
2224
0
    NULL );
2225
0
#endif
2226
0
  return( -1 );
2227
0
}
2228
2229
/* Reads (media) data at a specific offset
2230
 * Returns the number of bytes read or -1 on error
2231
 */
2232
ssize_t libsmraw_handle_read_buffer_at_offset(
2233
         libsmraw_handle_t *handle,
2234
         void *buffer,
2235
         size_t buffer_size,
2236
         off64_t offset,
2237
         libcerror_error_t **error )
2238
0
{
2239
0
  static char *function = "libsmraw_handle_read_buffer_at_offset";
2240
0
  ssize_t read_count    = 0;
2241
2242
0
  if( libsmraw_handle_seek_offset(
2243
0
       handle,
2244
0
       offset,
2245
0
       SEEK_SET,
2246
0
       error ) == -1 )
2247
0
  {
2248
0
    libcerror_error_set(
2249
0
     error,
2250
0
     LIBCERROR_ERROR_DOMAIN_IO,
2251
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
2252
0
     "%s: unable to seek offset.",
2253
0
     function );
2254
2255
0
    return( -1 );
2256
0
  }
2257
0
  read_count = libsmraw_handle_read_buffer(
2258
0
                handle,
2259
0
                buffer,
2260
0
                buffer_size,
2261
0
                error );
2262
2263
0
  if( read_count < 0 )
2264
0
  {
2265
0
    libcerror_error_set(
2266
0
     error,
2267
0
     LIBCERROR_ERROR_DOMAIN_IO,
2268
0
     LIBCERROR_IO_ERROR_READ_FAILED,
2269
0
     "%s: unable to read buffer.",
2270
0
     function );
2271
2272
0
    return( -1 );
2273
0
  }
2274
0
  return( read_count );
2275
0
}
2276
2277
/* Writes a buffer
2278
 * Returns the number of bytes written or -1 on error
2279
 */
2280
ssize_t libsmraw_handle_write_buffer(
2281
         libsmraw_handle_t *handle,
2282
         const void *buffer,
2283
         size_t buffer_size,
2284
         libcerror_error_t **error )
2285
0
{
2286
0
  libsmraw_internal_handle_t *internal_handle = NULL;
2287
0
  static char *function                       = "libsmraw_handle_write_buffer";
2288
0
  off64_t current_offset                      = 0;
2289
0
  ssize_t write_count                         = 0;
2290
2291
0
  if( handle == NULL )
2292
0
  {
2293
0
    libcerror_error_set(
2294
0
     error,
2295
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2296
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2297
0
     "%s: invalid handle.",
2298
0
     function );
2299
2300
0
    return( -1 );
2301
0
  }
2302
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
2303
2304
0
  if( internal_handle->io_handle == NULL )
2305
0
  {
2306
0
    libcerror_error_set(
2307
0
     error,
2308
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2309
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2310
0
     "%s: invalid handle - missing IO handle.",
2311
0
     function );
2312
2313
0
    return( -1 );
2314
0
  }
2315
0
  if( internal_handle->file_io_pool == NULL )
2316
0
  {
2317
0
    libcerror_error_set(
2318
0
     error,
2319
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2320
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2321
0
     "%s: invalid handle - missing file IO pool.",
2322
0
     function );
2323
2324
0
    return( -1 );
2325
0
  }
2326
0
  if( internal_handle->write_values_initialized == 0 )
2327
0
  {
2328
0
    if( libsmraw_internal_handle_initialize_write_values(
2329
0
         internal_handle,
2330
0
         error ) != 1 )
2331
0
    {
2332
0
      libcerror_error_set(
2333
0
       error,
2334
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2335
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2336
0
       "%s: unable to initialize write values.",
2337
0
       function );
2338
2339
0
      return( -1 );
2340
0
    }
2341
0
  }
2342
  /* Bail out early for requests to write empty buffers
2343
   */
2344
0
  if( buffer_size == 0 )
2345
0
  {
2346
0
    return( 0 );
2347
0
  }
2348
0
  if( libfdata_stream_get_offset(
2349
0
       internal_handle->segments_stream,
2350
0
       &current_offset,
2351
0
       error ) != 1 )
2352
0
  {
2353
0
    libcerror_error_set(
2354
0
     error,
2355
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2356
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2357
0
     "%s: unable to retrieve current offset from segments stream.",
2358
0
     function );
2359
2360
0
    return( -1 );
2361
0
  }
2362
0
  if( current_offset < 0 )
2363
0
  {
2364
0
    libcerror_error_set(
2365
0
     error,
2366
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2367
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2368
0
     "%s: invalid current offset value out of bounds.",
2369
0
     function );
2370
2371
0
    return( -1 );
2372
0
  }
2373
0
  if( internal_handle->io_handle->media_size > 0 )
2374
0
  {
2375
    /* Bail out early for requests to write beyond the media size
2376
     */
2377
0
    if( (size64_t) current_offset >= internal_handle->io_handle->media_size )
2378
0
    {
2379
0
      return( 0 );
2380
0
    }
2381
0
    if( ( (size64_t) current_offset + buffer_size ) >= internal_handle->io_handle->media_size )
2382
0
    {
2383
0
      buffer_size = (size_t) ( internal_handle->io_handle->media_size - (size64_t) current_offset );
2384
0
    }
2385
0
  }
2386
0
  write_count = libfdata_stream_write_buffer(
2387
0
                 internal_handle->segments_stream,
2388
0
                 (intptr_t *) internal_handle->file_io_pool,
2389
0
                 (uint8_t *) buffer,
2390
0
                 buffer_size,
2391
0
                 0,
2392
0
                 error );
2393
2394
0
  if( write_count < 0 )
2395
0
  {
2396
0
    libcerror_error_set(
2397
0
     error,
2398
0
     LIBCERROR_ERROR_DOMAIN_IO,
2399
0
     LIBCERROR_IO_ERROR_READ_FAILED,
2400
0
     "%s: unable to write buffer to segments stream.",
2401
0
     function );
2402
2403
0
    return( -1 );
2404
0
  }
2405
0
  return( write_count );
2406
0
}
2407
2408
/* Writes (media) data at a specific offset,
2409
 * Returns the number of input bytes written, 0 when no longer bytes can be written or -1 on error
2410
 */
2411
ssize_t libsmraw_handle_write_buffer_at_offset(
2412
         libsmraw_handle_t *handle,
2413
         const void *buffer,
2414
         size_t buffer_size,
2415
         off64_t offset,
2416
         libcerror_error_t **error )
2417
0
{
2418
0
  static char *function = "libsmraw_handle_write_buffer_at_offset";
2419
0
  ssize_t write_count   = 0;
2420
2421
0
  if( libsmraw_handle_seek_offset(
2422
0
       handle,
2423
0
       offset,
2424
0
       SEEK_SET,
2425
0
       error ) == -1 )
2426
0
  {
2427
0
    libcerror_error_set(
2428
0
     error,
2429
0
     LIBCERROR_ERROR_DOMAIN_IO,
2430
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
2431
0
     "%s: unable to seek offset.",
2432
0
     function );
2433
2434
0
    return( -1 );
2435
0
  }
2436
0
  write_count = libsmraw_handle_write_buffer(
2437
0
                 handle,
2438
0
                 buffer,
2439
0
                 buffer_size,
2440
0
                 error );
2441
2442
0
  if( write_count < 0 )
2443
0
  {
2444
0
    libcerror_error_set(
2445
0
     error,
2446
0
     LIBCERROR_ERROR_DOMAIN_IO,
2447
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
2448
0
     "%s: unable to write buffer.",
2449
0
     function );
2450
2451
0
    return( -1 );
2452
0
  }
2453
0
  return( write_count );
2454
0
}
2455
2456
/* Seeks a certain offset
2457
 * Returns the offset or -1 on error
2458
 */
2459
off64_t libsmraw_handle_seek_offset(
2460
         libsmraw_handle_t *handle,
2461
         off64_t offset,
2462
         int whence,
2463
         libcerror_error_t **error )
2464
0
{
2465
0
  libsmraw_internal_handle_t *internal_handle = NULL;
2466
0
  static char *function                       = "libsmraw_handle_seek_offset";
2467
2468
0
  if( handle == NULL )
2469
0
  {
2470
0
    libcerror_error_set(
2471
0
     error,
2472
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2473
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2474
0
     "%s: invalid handle.",
2475
0
     function );
2476
2477
0
    return( -1 );
2478
0
  }
2479
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
2480
2481
0
  if( internal_handle->file_io_pool == NULL )
2482
0
  {
2483
0
    libcerror_error_set(
2484
0
     error,
2485
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2486
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2487
0
     "%s: invalid handle - missing file IO pool.",
2488
0
     function );
2489
2490
0
    return( -1 );
2491
0
  }
2492
0
  offset = libfdata_stream_seek_offset(
2493
0
            internal_handle->segments_stream,
2494
0
            offset,
2495
0
            whence,
2496
0
            error );
2497
2498
0
  if( offset == -1 )
2499
0
  {
2500
0
    libcerror_error_set(
2501
0
     error,
2502
0
     LIBCERROR_ERROR_DOMAIN_IO,
2503
0
     LIBCERROR_IO_ERROR_READ_FAILED,
2504
0
     "%s: unable to seek offset in segments stream.",
2505
0
     function );
2506
2507
0
    return( -1 );
2508
0
  }
2509
0
  return( offset );
2510
0
}
2511
2512
/* Retrieves the current offset of the (media) data
2513
 * Returns 1 if successful or -1 on error
2514
 */
2515
int libsmraw_handle_get_offset(
2516
     libsmraw_handle_t *handle,
2517
     off64_t *offset,
2518
     libcerror_error_t **error )
2519
0
{
2520
0
  libsmraw_internal_handle_t *internal_handle = NULL;
2521
0
  static char *function                       = "libsmraw_handle_get_offset";
2522
2523
0
  if( handle == NULL )
2524
0
  {
2525
0
    libcerror_error_set(
2526
0
     error,
2527
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2528
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2529
0
     "%s: invalid handle.",
2530
0
     function );
2531
2532
0
    return( -1 );
2533
0
  }
2534
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
2535
2536
0
  if( libfdata_stream_get_offset(
2537
0
       internal_handle->segments_stream,
2538
0
       offset,
2539
0
       error ) != 1 )
2540
0
  {
2541
0
    libcerror_error_set(
2542
0
     error,
2543
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2544
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2545
0
     "%s: unable to retrieve offset from segments stream.",
2546
0
     function );
2547
2548
0
    return( -1 );
2549
0
  }
2550
0
  return( 1 );
2551
0
}
2552
2553
/* Sets the maximum number of (concurrent) open file handles
2554
 * Returns 1 if successful or -1 on error
2555
 */
2556
int libsmraw_handle_set_maximum_number_of_open_handles(
2557
     libsmraw_handle_t *handle,
2558
     int maximum_number_of_open_handles,
2559
     libcerror_error_t **error )
2560
0
{
2561
0
  libsmraw_internal_handle_t *internal_handle = NULL;
2562
0
  static char *function                       = "libsmraw_handle_set_maximum_number_of_open_handles";
2563
2564
0
  if( handle == NULL )
2565
0
  {
2566
0
    libcerror_error_set(
2567
0
     error,
2568
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2569
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2570
0
     "%s: invalid handle.",
2571
0
     function );
2572
2573
0
    return( -1 );
2574
0
  }
2575
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
2576
2577
0
  if( internal_handle->file_io_pool != NULL )
2578
0
  {
2579
0
    if( libbfio_pool_set_maximum_number_of_open_handles(
2580
0
         internal_handle->file_io_pool,
2581
0
         maximum_number_of_open_handles,
2582
0
         error ) != 1 )
2583
0
    {
2584
0
      libcerror_error_set(
2585
0
       error,
2586
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2587
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2588
0
       "%s: unable to set maximum number of open handles in file IO handle.",
2589
0
       function );
2590
2591
0
      return( -1 );
2592
0
    }
2593
0
  }
2594
0
  internal_handle->maximum_number_of_open_handles = maximum_number_of_open_handles;
2595
2596
0
  return( 1 );
2597
0
}
2598
2599
/* Retrieves the segment filename size
2600
 * The segment filename size includes the end of string character
2601
 * Returns 1 if succesful or -1 on error
2602
 */
2603
int libsmraw_handle_get_segment_filename_size(
2604
     libsmraw_handle_t *handle,
2605
     size_t *filename_size,
2606
     libcerror_error_t **error )
2607
0
{
2608
0
  libsmraw_internal_handle_t *internal_handle = NULL;
2609
0
  static char *function                       = "libsmraw_handle_get_segment_filename_size";
2610
2611
0
  if( handle == NULL )
2612
0
  {
2613
0
    libcerror_error_set(
2614
0
     error,
2615
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2616
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2617
0
     "%s: invalid handle.",
2618
0
     function );
2619
2620
0
    return( -1 );
2621
0
  }
2622
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
2623
2624
0
  if( libsmraw_io_handle_get_basename_size(
2625
0
       internal_handle->io_handle,
2626
0
       filename_size,
2627
0
       error ) != 1 )
2628
0
  {
2629
0
    libcerror_error_set(
2630
0
     error,
2631
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2632
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2633
0
     "%s: unable to retrieve basename size from IO handle.",
2634
0
     function );
2635
2636
0
    return( -1 );
2637
0
  }
2638
0
  return( 1 );
2639
0
}
2640
2641
/* Retrieves the segment filename
2642
 * The segment filename size should include the end of string character
2643
 * Returns 1 if succesful or -1 on error
2644
 */
2645
int libsmraw_handle_get_segment_filename(
2646
     libsmraw_handle_t *handle,
2647
     char *filename,
2648
     size_t filename_size,
2649
     libcerror_error_t **error )
2650
0
{
2651
0
  libsmraw_internal_handle_t *internal_handle = NULL;
2652
0
  static char *function                       = "libsmraw_handle_get_segment_filename";
2653
2654
0
  if( handle == NULL )
2655
0
  {
2656
0
    libcerror_error_set(
2657
0
     error,
2658
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2659
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2660
0
     "%s: invalid handle.",
2661
0
     function );
2662
2663
0
    return( -1 );
2664
0
  }
2665
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
2666
2667
0
  if( libsmraw_io_handle_get_basename(
2668
0
       internal_handle->io_handle,
2669
0
       filename,
2670
0
       filename_size,
2671
0
       error ) != 1 )
2672
0
  {
2673
0
    libcerror_error_set(
2674
0
     error,
2675
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2676
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2677
0
     "%s: unable to retrieve basename from IO handle.",
2678
0
     function );
2679
2680
0
    return( -1 );
2681
0
  }
2682
0
  return( 1 );
2683
0
}
2684
2685
/* Sets the segment filename
2686
 * Returns 1 if succesful or -1 on error
2687
 */
2688
int libsmraw_handle_set_segment_filename(
2689
     libsmraw_handle_t *handle,
2690
     const char *filename,
2691
     size_t filename_length,
2692
     libcerror_error_t **error )
2693
0
{
2694
0
  libsmraw_internal_handle_t *internal_handle = NULL;
2695
0
  static char *function                       = "libsmraw_handle_set_segment_filename";
2696
2697
0
  if( handle == NULL )
2698
0
  {
2699
0
    libcerror_error_set(
2700
0
     error,
2701
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2702
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2703
0
     "%s: invalid handle.",
2704
0
     function );
2705
2706
0
    return( -1 );
2707
0
  }
2708
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
2709
2710
0
  if( internal_handle->io_handle == NULL )
2711
0
  {
2712
0
    libcerror_error_set(
2713
0
     error,
2714
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2715
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2716
0
     "%s: invalid handle - missing IO handle.",
2717
0
     function );
2718
2719
0
    return( -1 );
2720
0
  }
2721
0
  if( internal_handle->io_handle->basename != NULL )
2722
0
  {
2723
0
    if( internal_handle->file_io_pool != NULL )
2724
0
    {
2725
0
      libcerror_error_set(
2726
0
       error,
2727
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2728
0
       LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2729
0
       "%s: basename value already set: %" PRIs_SYSTEM ".",
2730
0
       function,
2731
0
       internal_handle->io_handle->basename );
2732
2733
0
      return( -1 );
2734
0
    }
2735
0
  }
2736
0
  if( libsmraw_io_handle_set_basename(
2737
0
       internal_handle->io_handle,
2738
0
       filename,
2739
0
       filename_length,
2740
0
       error ) != 1 )
2741
0
  {
2742
0
    libcerror_error_set(
2743
0
     error,
2744
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2745
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2746
0
     "%s: unable to set basename in IO handle.",
2747
0
     function );
2748
2749
0
    return( -1 );
2750
0
  }
2751
0
  return( 1 );
2752
0
}
2753
2754
#if defined( HAVE_WIDE_CHARACTER_TYPE )
2755
2756
/* Retrieves the segment filename size
2757
 * The segment filename size includes the end of string character
2758
 * Returns 1 if succesful or -1 on error
2759
 */
2760
int libsmraw_handle_get_segment_filename_size_wide(
2761
     libsmraw_handle_t *handle,
2762
     size_t *filename_size,
2763
     libcerror_error_t **error )
2764
{
2765
  libsmraw_internal_handle_t *internal_handle = NULL;
2766
  static char *function                       = "libsmraw_handle_get_segment_filename_size_wide";
2767
2768
  if( handle == NULL )
2769
  {
2770
    libcerror_error_set(
2771
     error,
2772
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2773
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2774
     "%s: invalid handle.",
2775
     function );
2776
2777
    return( -1 );
2778
  }
2779
  internal_handle = (libsmraw_internal_handle_t *) handle;
2780
2781
  if( libsmraw_io_handle_get_basename_size_wide(
2782
       internal_handle->io_handle,
2783
       filename_size,
2784
       error ) != 1 )
2785
  {
2786
    libcerror_error_set(
2787
     error,
2788
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2789
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2790
     "%s: unable to retrieve basename size from IO handle.",
2791
     function );
2792
2793
    return( -1 );
2794
  }
2795
  return( 1 );
2796
}
2797
2798
/* Retrieves the segment filename
2799
 * The segment filename size should include the end of string character
2800
 * Returns 1 if succesful or -1 on error
2801
 */
2802
int libsmraw_handle_get_segment_filename_wide(
2803
     libsmraw_handle_t *handle,
2804
     wchar_t *filename,
2805
     size_t filename_size,
2806
     libcerror_error_t **error )
2807
{
2808
  libsmraw_internal_handle_t *internal_handle = NULL;
2809
  static char *function                      = "libsmraw_handle_get_segment_filename_wide";
2810
2811
  if( handle == NULL )
2812
  {
2813
    libcerror_error_set(
2814
     error,
2815
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2816
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2817
     "%s: invalid handle.",
2818
     function );
2819
2820
    return( -1 );
2821
  }
2822
  internal_handle = (libsmraw_internal_handle_t *) handle;
2823
2824
  if( libsmraw_io_handle_get_basename_wide(
2825
       internal_handle->io_handle,
2826
       filename,
2827
       filename_size,
2828
       error ) != 1 )
2829
  {
2830
    libcerror_error_set(
2831
     error,
2832
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2833
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2834
     "%s: unable to retrieve basename from IO handle.",
2835
     function );
2836
2837
    return( -1 );
2838
  }
2839
  return( 1 );
2840
}
2841
2842
/* Sets the segment filename
2843
 * Returns 1 if succesful or -1 on error
2844
 */
2845
int libsmraw_handle_set_segment_filename_wide(
2846
     libsmraw_handle_t *handle,
2847
     const wchar_t *filename,
2848
     size_t filename_length,
2849
     libcerror_error_t **error )
2850
{
2851
  libsmraw_internal_handle_t *internal_handle = NULL;
2852
  static char *function                       = "libsmraw_handle_set_segment_filename_wide";
2853
2854
  if( handle == NULL )
2855
  {
2856
    libcerror_error_set(
2857
     error,
2858
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2859
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2860
     "%s: invalid handle.",
2861
     function );
2862
2863
    return( -1 );
2864
  }
2865
  internal_handle = (libsmraw_internal_handle_t *) handle;
2866
2867
  if( internal_handle->io_handle == NULL )
2868
  {
2869
    libcerror_error_set(
2870
     error,
2871
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2872
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2873
     "%s: invalid handle - missing IO handle.",
2874
     function );
2875
2876
    return( -1 );
2877
  }
2878
  if( internal_handle->io_handle->basename != NULL )
2879
  {
2880
    if( internal_handle->file_io_pool != NULL )
2881
    {
2882
      libcerror_error_set(
2883
       error,
2884
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2885
       LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2886
       "%s: basename value already set: %" PRIs_SYSTEM ".",
2887
       function,
2888
       internal_handle->io_handle->basename );
2889
2890
      return( -1 );
2891
    }
2892
  }
2893
  if( libsmraw_io_handle_set_basename_wide(
2894
       internal_handle->io_handle,
2895
       filename,
2896
       filename_length,
2897
       error ) != 1 )
2898
  {
2899
    libcerror_error_set(
2900
     error,
2901
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2902
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2903
     "%s: unable to set basename in IO handle.",
2904
     function );
2905
2906
    return( -1 );
2907
  }
2908
  return( 1 );
2909
}
2910
2911
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
2912
2913
/* Retrieves the segment file size
2914
 * 0 represents the maximum possible segment file size
2915
 * Returns 1 if successful or -1 on error
2916
 */
2917
int libsmraw_handle_get_maximum_segment_size(
2918
     libsmraw_handle_t *handle,
2919
     size64_t *maximum_segment_size,
2920
     libcerror_error_t **error )
2921
0
{
2922
0
  libsmraw_internal_handle_t *internal_handle = NULL;
2923
0
  static char *function                       = "libsmraw_handle_get_maximum_segment_size";
2924
2925
0
  if( handle == NULL )
2926
0
  {
2927
0
    libcerror_error_set(
2928
0
     error,
2929
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2930
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2931
0
     "%s: invalid handle.",
2932
0
     function );
2933
2934
0
    return( -1 );
2935
0
  }
2936
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
2937
2938
0
  if( libsmraw_io_handle_get_maximum_segment_size(
2939
0
       internal_handle->io_handle,
2940
0
       maximum_segment_size,
2941
0
       error ) != 1 )
2942
0
  {
2943
0
    libcerror_error_set(
2944
0
     error,
2945
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2946
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2947
0
     "%s: unable to retrieve maximum segment size from IO handle.",
2948
0
     function );
2949
2950
0
    return( -1 );
2951
0
  }
2952
0
  return( 1 );
2953
0
}
2954
2955
/* Sets the segment file size
2956
 * 0 represents the maximum possible segment file size
2957
 * Returns 1 if successful or -1 on error
2958
 */
2959
int libsmraw_handle_set_maximum_segment_size(
2960
     libsmraw_handle_t *handle,
2961
     size64_t maximum_segment_size,
2962
     libcerror_error_t **error )
2963
0
{
2964
0
  libsmraw_internal_handle_t *internal_handle = NULL;
2965
0
  static char *function                       = "libsmraw_handle_set_maximum_segment_size";
2966
2967
0
  if( handle == NULL )
2968
0
  {
2969
0
    libcerror_error_set(
2970
0
     error,
2971
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2972
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2973
0
     "%s: invalid handle.",
2974
0
     function );
2975
2976
0
    return( -1 );
2977
0
  }
2978
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
2979
2980
0
  if( internal_handle->write_values_initialized != 0 )
2981
0
  {
2982
0
    libcerror_error_set(
2983
0
     error,
2984
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2985
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2986
0
     "%s: maximum segment size cannot be changed.",
2987
0
     function );
2988
2989
0
    return( -1 );
2990
0
  }
2991
0
  if( libsmraw_io_handle_set_maximum_segment_size(
2992
0
       internal_handle->io_handle,
2993
0
       maximum_segment_size,
2994
0
       error ) != 1 )
2995
0
  {
2996
0
    libcerror_error_set(
2997
0
     error,
2998
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2999
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3000
0
     "%s: unable to set maximum segment size in IO handle.",
3001
0
     function );
3002
3003
0
    return( -1 );
3004
0
  }
3005
0
  return( 1 );
3006
0
}
3007
3008
/* Retrieves the filename size of the segment file of the current offset
3009
 * The filename size should include the end of string character
3010
 * Returns 1 if successful or -1 on error
3011
 */
3012
int libsmraw_handle_get_filename_size(
3013
     libsmraw_handle_t *handle,
3014
     size_t *filename_size,
3015
     libcerror_error_t **error )
3016
0
{
3017
0
  libbfio_handle_t *file_io_handle = NULL;
3018
0
  static char *function            = "libsmraw_handle_get_filename_size";
3019
3020
0
  if( handle == NULL )
3021
0
  {
3022
0
    libcerror_error_set(
3023
0
     error,
3024
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3025
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3026
0
     "%s: invalid handle.",
3027
0
     function );
3028
3029
0
    return( -1 );
3030
0
  }
3031
0
  if( libsmraw_handle_get_file_io_handle(
3032
0
       handle,
3033
0
       &file_io_handle,
3034
0
       error ) != 1 )
3035
0
  {
3036
0
    libcerror_error_set(
3037
0
     error,
3038
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3039
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3040
0
     "%s: unable to retrieve file IO handle for current offset.",
3041
0
     function );
3042
3043
0
    return( -1 );
3044
0
  }
3045
0
  if( libbfio_file_get_name_size(
3046
0
       file_io_handle,
3047
0
       filename_size,
3048
0
       error ) != 1 )
3049
0
  {
3050
0
    libcerror_error_set(
3051
0
     error,
3052
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3053
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3054
0
     "%s: unable to retrieve filename size.",
3055
0
     function );
3056
3057
0
    return( -1 );
3058
0
  }
3059
0
  return( 1 );
3060
0
}
3061
3062
/* Retrieves the filename of the segment file of the current offset
3063
 * The filename size should include the end of string character
3064
 * Returns 1 if successful or -1 on error
3065
 */
3066
int libsmraw_handle_get_filename(
3067
     libsmraw_handle_t *handle,
3068
     char *filename,
3069
     size_t filename_size,
3070
     libcerror_error_t **error )
3071
0
{
3072
0
  libbfio_handle_t *file_io_handle = NULL;
3073
0
  static char *function            = "libsmraw_handle_get_filename";
3074
3075
0
  if( handle == NULL )
3076
0
  {
3077
0
    libcerror_error_set(
3078
0
     error,
3079
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3080
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3081
0
     "%s: invalid handle.",
3082
0
     function );
3083
3084
0
    return( -1 );
3085
0
  }
3086
0
  if( libsmraw_handle_get_file_io_handle(
3087
0
       handle,
3088
0
       &file_io_handle,
3089
0
       error ) != 1 )
3090
0
  {
3091
0
    libcerror_error_set(
3092
0
     error,
3093
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3094
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3095
0
     "%s: unable to retrieve file IO handle for current offset.",
3096
0
     function );
3097
3098
0
    return( -1 );
3099
0
  }
3100
0
  if( libbfio_file_get_name(
3101
0
       file_io_handle,
3102
0
       filename,
3103
0
       filename_size,
3104
0
       error ) != 1 )
3105
0
  {
3106
0
    libcerror_error_set(
3107
0
     error,
3108
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3109
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3110
0
     "%s: unable to retrieve filename.",
3111
0
     function );
3112
3113
0
    return( -1 );
3114
0
  }
3115
0
  return( 1 );
3116
0
}
3117
3118
#if defined( HAVE_WIDE_CHARACTER_TYPE )
3119
3120
/* Retrieves the filename size of the segment file of the current offset
3121
 * The filename size includes the end of string character
3122
 * Returns 1 if successful or -1 on error
3123
 */
3124
int libsmraw_handle_get_filename_size_wide(
3125
     libsmraw_handle_t *handle,
3126
     size_t *filename_size,
3127
     libcerror_error_t **error )
3128
{
3129
  libbfio_handle_t *file_io_handle = NULL;
3130
  static char *function            = "libsmraw_handle_get_filename_size_wide";
3131
3132
  if( handle == NULL )
3133
  {
3134
    libcerror_error_set(
3135
     error,
3136
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3137
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3138
     "%s: invalid handle.",
3139
     function );
3140
3141
    return( -1 );
3142
  }
3143
  if( libsmraw_handle_get_file_io_handle(
3144
       handle,
3145
       &file_io_handle,
3146
       error ) != 1 )
3147
  {
3148
    libcerror_error_set(
3149
     error,
3150
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3151
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3152
     "%s: unable to retrieve file IO handle for current offset.",
3153
     function );
3154
3155
    return( -1 );
3156
  }
3157
  if( libbfio_file_get_name_size_wide(
3158
       file_io_handle,
3159
       filename_size,
3160
       error ) != 1 )
3161
  {
3162
    libcerror_error_set(
3163
     error,
3164
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3165
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3166
     "%s: unable to retrieve filename size.",
3167
     function );
3168
3169
    return( -1 );
3170
  }
3171
  return( 1 );
3172
}
3173
3174
/* Retrieves the filename of the segment file of the current offset
3175
 * The filename size should include the end of string character
3176
 * Returns 1 if successful or -1 on error
3177
 */
3178
int libsmraw_handle_get_filename_wide(
3179
     libsmraw_handle_t *handle,
3180
     wchar_t *filename,
3181
     size_t filename_size,
3182
     libcerror_error_t **error )
3183
{
3184
  libbfio_handle_t *file_io_handle = NULL;
3185
  static char *function            = "libsmraw_handle_get_filename_wide";
3186
3187
  if( handle == NULL )
3188
  {
3189
    libcerror_error_set(
3190
     error,
3191
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3192
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3193
     "%s: invalid handle.",
3194
     function );
3195
3196
    return( -1 );
3197
  }
3198
  if( libsmraw_handle_get_file_io_handle(
3199
       handle,
3200
       &file_io_handle,
3201
       error ) != 1 )
3202
  {
3203
    libcerror_error_set(
3204
     error,
3205
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3206
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3207
     "%s: unable to retrieve file IO handle for current offset.",
3208
     function );
3209
3210
    return( -1 );
3211
  }
3212
  if( libbfio_file_get_name_wide(
3213
       file_io_handle,
3214
       filename,
3215
       filename_size,
3216
       error ) != 1 )
3217
  {
3218
    libcerror_error_set(
3219
     error,
3220
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3221
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3222
     "%s: unable to retrieve filename.",
3223
     function );
3224
3225
    return( -1 );
3226
  }
3227
  return( 1 );
3228
}
3229
3230
#endif
3231
3232
/* Retrieves the file IO handle of the segment file of the current offset
3233
 * Returns 1 if successful or -1 on error
3234
 */
3235
int libsmraw_handle_get_file_io_handle(
3236
     libsmraw_handle_t *handle,
3237
     libbfio_handle_t **file_io_handle,
3238
     libcerror_error_t **error )
3239
0
{
3240
0
  libsmraw_internal_handle_t *internal_handle = NULL;
3241
0
  static char *function                       = "libsmraw_handle_get_file_io_handle";
3242
0
  off64_t current_offset                      = 0;
3243
0
  off64_t segment_data_offset                 = 0;
3244
0
  int segment_index                           = 0;
3245
3246
0
  if( handle == NULL )
3247
0
  {
3248
0
    libcerror_error_set(
3249
0
     error,
3250
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3251
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3252
0
     "%s: invalid handle.",
3253
0
     function );
3254
3255
0
    return( -1 );
3256
0
  }
3257
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
3258
3259
0
  if( internal_handle->file_io_pool == NULL )
3260
0
  {
3261
0
    libcerror_error_set(
3262
0
     error,
3263
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3264
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3265
0
     "%s: invalid handle - missing file IO pool.",
3266
0
     function );
3267
3268
0
    return( -1 );
3269
0
  }
3270
0
  if( libfdata_stream_get_offset(
3271
0
       internal_handle->segments_stream,
3272
0
       &current_offset,
3273
0
       error ) != 1 )
3274
0
  {
3275
0
    libcerror_error_set(
3276
0
     error,
3277
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3278
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3279
0
     "%s: unable to retrieve current offset from segments stream.",
3280
0
     function );
3281
3282
0
    return( -1 );
3283
0
  }
3284
0
  if( libfdata_stream_get_segment_index_at_offset(
3285
0
       internal_handle->segments_stream,
3286
0
       current_offset,
3287
0
       &segment_index,
3288
0
       &segment_data_offset,
3289
0
       error ) != 1 )
3290
0
  {
3291
0
    libcerror_error_set(
3292
0
     error,
3293
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3294
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3295
0
     "%s: unable to retrieve segment index at offset: %" PRIi64 " (0x%08" PRIx64 ") from segments stream.",
3296
0
     function,
3297
0
     current_offset,
3298
0
     current_offset );
3299
3300
0
    return( -1 );
3301
0
  }
3302
0
  if( libbfio_pool_get_handle(
3303
0
       internal_handle->file_io_pool,
3304
0
       segment_index,
3305
0
       file_io_handle,
3306
0
       error ) != 1 )
3307
0
  {
3308
0
    libcerror_error_set(
3309
0
     error,
3310
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3311
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3312
0
     "%s: unable to retrieve file IO handle for pool entry: %d at offset: %" PRIi64 " (0x%08" PRIx64 ").",
3313
0
     function,
3314
0
     segment_index,
3315
0
     current_offset,
3316
0
     current_offset );
3317
3318
0
    return( -1 );
3319
0
  }
3320
0
  return( 1 );
3321
0
}
3322
3323
/* Retrieves the media size
3324
 * Returns the 1 if succesful or -1 on error
3325
 */
3326
int libsmraw_handle_get_media_size(
3327
     libsmraw_handle_t *handle,
3328
     size64_t *media_size,
3329
     libcerror_error_t **error )
3330
0
{
3331
0
  libsmraw_internal_handle_t *internal_handle = NULL;
3332
0
  static char *function                       = "libsmraw_handle_get_media_size";
3333
3334
0
  if( handle == NULL )
3335
0
  {
3336
0
    libcerror_error_set(
3337
0
     error,
3338
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3339
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3340
0
     "%s: invalid handle.",
3341
0
     function );
3342
3343
0
    return( -1 );
3344
0
  }
3345
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
3346
3347
0
  if( internal_handle->io_handle == NULL )
3348
0
  {
3349
0
    libcerror_error_set(
3350
0
     error,
3351
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3352
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3353
0
     "%s: invalid handle - missing IO handle.",
3354
0
     function );
3355
3356
0
    return( -1 );
3357
0
  }
3358
0
  if( internal_handle->file_io_pool == NULL )
3359
0
  {
3360
0
    libcerror_error_set(
3361
0
     error,
3362
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3363
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3364
0
     "%s: invalid handle - missing file IO pool.",
3365
0
     function );
3366
3367
0
    return( -1 );
3368
0
  }
3369
0
  if( media_size == NULL )
3370
0
  {
3371
0
    libcerror_error_set(
3372
0
     error,
3373
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3374
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3375
0
     "%s: invalid media size.",
3376
0
     function );
3377
3378
0
    return( -1 );
3379
0
  }
3380
0
#if defined( HAVE_LIBSMRAW_MULTI_THREAD_SUPPORT )
3381
0
  if( libcthreads_read_write_lock_grab_for_read(
3382
0
       internal_handle->read_write_lock,
3383
0
       error ) != 1 )
3384
0
  {
3385
0
    libcerror_error_set(
3386
0
     error,
3387
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3388
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3389
0
     "%s: unable to grab read/write lock for reading.",
3390
0
     function );
3391
3392
0
    return( -1 );
3393
0
  }
3394
0
#endif
3395
0
  *media_size = internal_handle->io_handle->media_size;
3396
3397
0
#if defined( HAVE_LIBSMRAW_MULTI_THREAD_SUPPORT )
3398
0
  if( libcthreads_read_write_lock_release_for_read(
3399
0
       internal_handle->read_write_lock,
3400
0
       error ) != 1 )
3401
0
  {
3402
0
    libcerror_error_set(
3403
0
     error,
3404
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3405
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3406
0
     "%s: unable to release read/write lock for reading.",
3407
0
     function );
3408
3409
0
    return( -1 );
3410
0
  }
3411
0
#endif
3412
0
  return( 1 );
3413
0
}
3414
3415
/* Sets the media size
3416
 * Returns the 1 if succesful or -1 on error
3417
 */
3418
int libsmraw_handle_set_media_size(
3419
     libsmraw_handle_t *handle,
3420
     size64_t media_size,
3421
     libcerror_error_t **error )
3422
0
{
3423
0
  libsmraw_internal_handle_t *internal_handle = NULL;
3424
0
  static char *function                       = "libsmraw_handle_set_media_size";
3425
3426
0
  if( handle == NULL )
3427
0
  {
3428
0
    libcerror_error_set(
3429
0
     error,
3430
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3431
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3432
0
     "%s: invalid handle.",
3433
0
     function );
3434
3435
0
    return( -1 );
3436
0
  }
3437
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
3438
3439
0
  if( internal_handle->io_handle == NULL )
3440
0
  {
3441
0
    libcerror_error_set(
3442
0
     error,
3443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3444
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3445
0
     "%s: invalid handle - missing IO handle.",
3446
0
     function );
3447
3448
0
    return( -1 );
3449
0
  }
3450
0
  if( ( internal_handle->read_values_initialized != 0 )
3451
0
   || ( internal_handle->write_values_initialized != 0 ) )
3452
0
  {
3453
0
    libcerror_error_set(
3454
0
     error,
3455
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3456
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3457
0
     "%s: media size cannot be changed.",
3458
0
     function );
3459
3460
0
    return( -1 );
3461
0
  }
3462
/* TODO add thread-safety support */
3463
0
  internal_handle->io_handle->media_size = media_size;
3464
3465
0
  return( 1 );
3466
0
}
3467
3468
/* Retrieves the bytes per sector
3469
 * Returns the 1 if succesful or -1 on error
3470
 */
3471
int libsmraw_handle_get_bytes_per_sector(
3472
     libsmraw_handle_t *handle,
3473
     uint32_t *bytes_per_sector,
3474
     libcerror_error_t **error )
3475
0
{
3476
0
  libsmraw_internal_handle_t *internal_handle = NULL;
3477
0
  libfvalue_value_t *value                    = NULL;
3478
0
  static char *function                       = "libsmraw_handle_get_bytes_per_sector";
3479
0
  const char *identifier                      = "bytes_per_sector";
3480
0
  size_t identifier_size                      = 16;
3481
0
  uint64_t value_64bit                        = 0;
3482
0
  int result                                  = 0;
3483
3484
0
  if( handle == NULL )
3485
0
  {
3486
0
    libcerror_error_set(
3487
0
     error,
3488
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3489
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3490
0
     "%s: invalid handle.",
3491
0
     function );
3492
3493
0
    return( -1 );
3494
0
  }
3495
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
3496
3497
0
  if( bytes_per_sector == NULL )
3498
0
  {
3499
0
    libcerror_error_set(
3500
0
     error,
3501
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3502
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3503
0
     "%s: invalid bytes per sector.",
3504
0
     function );
3505
3506
0
    return( -1 );
3507
0
  }
3508
0
#if defined( HAVE_LIBSMRAW_MULTI_THREAD_SUPPORT )
3509
0
  if( libcthreads_read_write_lock_grab_for_read(
3510
0
       internal_handle->read_write_lock,
3511
0
       error ) != 1 )
3512
0
  {
3513
0
    libcerror_error_set(
3514
0
     error,
3515
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3516
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3517
0
     "%s: unable to grab read/write lock for reading.",
3518
0
     function );
3519
3520
0
    return( -1 );
3521
0
  }
3522
0
#endif
3523
0
  *bytes_per_sector = 0;
3524
3525
/* TODO refactor into media_values_get_64bit_value function ? */
3526
0
  result = libfvalue_table_get_value_by_identifier(
3527
0
            internal_handle->media_values,
3528
0
            (uint8_t *) identifier,
3529
0
            identifier_size,
3530
0
            &value,
3531
0
            0,
3532
0
            error );
3533
3534
0
  if( result == -1 )
3535
0
  {
3536
0
    libcerror_error_set(
3537
0
     error,
3538
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3539
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3540
0
     "%s: unable to retrieve value: %s from media values table.",
3541
0
     function,
3542
0
     identifier );
3543
3544
0
    goto on_error;
3545
0
  }
3546
0
  else if( result != 0 )
3547
0
  {
3548
0
    if( libfvalue_value_copy_to_64bit(
3549
0
         value,
3550
0
         0,
3551
0
         &value_64bit,
3552
0
         error ) != 1 )
3553
0
    {
3554
0
      libcerror_error_set(
3555
0
       error,
3556
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3557
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
3558
0
       "%s: unable to copy value to a 64-bit value.",
3559
0
       function );
3560
3561
0
      goto on_error;
3562
0
    }
3563
0
    if( value_64bit > (uint64_t) UINT32_MAX )
3564
0
    {
3565
0
      libcerror_error_set(
3566
0
       error,
3567
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3568
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3569
0
       "%s: 64-bit bytes per sector value out of bounds.",
3570
0
       function );
3571
3572
0
      goto on_error;
3573
0
    }
3574
0
    *bytes_per_sector = (uint32_t) value_64bit;
3575
0
  }
3576
0
#if defined( HAVE_LIBSMRAW_MULTI_THREAD_SUPPORT )
3577
0
  if( libcthreads_read_write_lock_release_for_read(
3578
0
       internal_handle->read_write_lock,
3579
0
       error ) != 1 )
3580
0
  {
3581
0
    libcerror_error_set(
3582
0
     error,
3583
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3584
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3585
0
     "%s: unable to release read/write lock for reading.",
3586
0
     function );
3587
3588
0
    return( -1 );
3589
0
  }
3590
0
#endif
3591
0
  return( 1 );
3592
3593
0
on_error:
3594
0
#if defined( HAVE_LIBSMRAW_MULTI_THREAD_SUPPORT )
3595
0
  libcthreads_read_write_lock_release_for_read(
3596
0
   internal_handle->read_write_lock,
3597
0
   NULL );
3598
0
#endif
3599
0
  return( -1 );
3600
0
}
3601
3602
/* Sets the bytes per sector
3603
 * Returns the 1 if succesful or -1 on error
3604
 */
3605
int libsmraw_handle_set_bytes_per_sector(
3606
     libsmraw_handle_t *handle,
3607
     uint32_t bytes_per_sector,
3608
     libcerror_error_t **error )
3609
0
{
3610
0
  libsmraw_internal_handle_t *internal_handle = NULL;
3611
0
  libfvalue_value_t *value                    = NULL;
3612
0
  static char *function                       = "libsmraw_handle_set_bytes_per_sector";
3613
0
  const char *identifier                      = "bytes_per_sector";
3614
0
  size_t identifier_size                      = 16;
3615
0
  int result                                  = 0;
3616
3617
0
  if( handle == NULL )
3618
0
  {
3619
0
    libcerror_error_set(
3620
0
     error,
3621
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3622
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3623
0
     "%s: invalid handle.",
3624
0
     function );
3625
3626
0
    return( -1 );
3627
0
  }
3628
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
3629
3630
0
  if( ( internal_handle->read_values_initialized != 0 )
3631
0
   || ( internal_handle->write_values_initialized != 0 ) )
3632
0
  {
3633
0
    libcerror_error_set(
3634
0
     error,
3635
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3636
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3637
0
     "%s: media values cannot be changed.",
3638
0
     function );
3639
3640
0
    return( -1 );
3641
0
  }
3642
/* TODO add thread-safety support */
3643
/* TODO refactor into media_values_set_64bit_value function ? */
3644
0
  result = libfvalue_table_get_value_by_identifier(
3645
0
            internal_handle->media_values,
3646
0
            (uint8_t *) identifier,
3647
0
            identifier_size,
3648
0
            &value,
3649
0
            0,
3650
0
            error );
3651
3652
0
  if( result == -1 )
3653
0
  {
3654
0
    libcerror_error_set(
3655
0
     error,
3656
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3657
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3658
0
     "%s: unable to retrieve value: %s from media values table.",
3659
0
     function,
3660
0
     identifier );
3661
3662
0
    return( -1 );
3663
0
  }
3664
0
  else if( result == 0 )
3665
0
  {
3666
0
    if( libfvalue_value_type_initialize(
3667
0
         &value,
3668
0
         LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_64BIT,
3669
0
         error ) != 1 )
3670
0
    {
3671
0
      libcerror_error_set(
3672
0
       error,
3673
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3674
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3675
0
       "%s: unable to create value.",
3676
0
       function );
3677
3678
0
      return( -1 );
3679
0
    }
3680
0
    if( libfvalue_value_set_identifier(
3681
0
         value,
3682
0
         (uint8_t *) identifier,
3683
0
         identifier_size,
3684
0
         LIBFVALUE_VALUE_IDENTIFIER_FLAG_MANAGED,
3685
0
         error ) != 1 )
3686
0
    {
3687
0
      libcerror_error_set(
3688
0
       error,
3689
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3690
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3691
0
       "%s: unable to set identifier in value.",
3692
0
       function );
3693
3694
0
      libfvalue_value_free(
3695
0
       &value,
3696
0
       NULL );
3697
3698
0
      return( -1 );
3699
0
    }
3700
0
    if( libfvalue_table_set_value(
3701
0
         internal_handle->media_values,
3702
0
         value,
3703
0
         error ) != 1 )
3704
0
    {
3705
0
      libcerror_error_set(
3706
0
       error,
3707
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3708
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3709
0
       "%s: unable to set value: %s in media values table.",
3710
0
       function,
3711
0
       identifier );
3712
3713
0
      libfvalue_value_free(
3714
0
       &value,
3715
0
       NULL );
3716
3717
0
      return( -1 );
3718
0
    }
3719
0
  }
3720
0
  if( libfvalue_value_copy_from_64bit(
3721
0
       value,
3722
0
       0,
3723
0
       (uint64_t) bytes_per_sector,
3724
0
       error ) != 1 )
3725
0
  {
3726
0
    libcerror_error_set(
3727
0
     error,
3728
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3729
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
3730
0
     "%s: unable to copy value from a 64-bit value.",
3731
0
     function );
3732
3733
0
    return( -1 );
3734
0
  }
3735
0
  return( 1 );
3736
0
}
3737
3738
/* Retrieves the media type
3739
 * Returns the 1 if succesful or -1 on error
3740
 */
3741
int libsmraw_handle_get_media_type(
3742
     libsmraw_handle_t *handle,
3743
     uint8_t *media_type,
3744
     libcerror_error_t **error )
3745
0
{
3746
0
  libsmraw_internal_handle_t *internal_handle = NULL;
3747
0
  libfvalue_value_t *value                    = NULL;
3748
0
  uint8_t *value_data                         = NULL;
3749
0
  static char *function                       = "libsmraw_handle_get_media_type";
3750
0
  const char *identifier                      = "media_type";
3751
0
  size_t identifier_size                      = 10;
3752
0
  size_t value_data_size                      = 0;
3753
0
  int encoding                                = 0;
3754
0
  int result                                  = 0;
3755
3756
0
  if( handle == NULL )
3757
0
  {
3758
0
    libcerror_error_set(
3759
0
     error,
3760
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3761
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3762
0
     "%s: invalid handle.",
3763
0
     function );
3764
3765
0
    return( -1 );
3766
0
  }
3767
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
3768
3769
0
  if( internal_handle->file_io_pool == NULL )
3770
0
  {
3771
0
    libcerror_error_set(
3772
0
     error,
3773
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3774
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3775
0
     "%s: invalid handle - missing file io pool.",
3776
0
     function );
3777
3778
0
    return( -1 );
3779
0
  }
3780
0
  if( media_type == NULL )
3781
0
  {
3782
0
    libcerror_error_set(
3783
0
     error,
3784
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3785
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3786
0
     "%s: invalid media type.",
3787
0
     function );
3788
3789
0
    return( -1 );
3790
0
  }
3791
/* TODO add thread-safety support */
3792
0
  *media_type = LIBSMRAW_MEDIA_TYPE_UNKNOWN;
3793
3794
0
  result = libfvalue_table_get_value_by_identifier(
3795
0
            internal_handle->media_values,
3796
0
            (uint8_t *) identifier,
3797
0
            identifier_size,
3798
0
            &value,
3799
0
            0,
3800
0
            error );
3801
3802
0
  if( result == -1 )
3803
0
  {
3804
0
    libcerror_error_set(
3805
0
     error,
3806
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3807
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3808
0
     "%s: unable to retrieve value: %s from media values table.",
3809
0
     function,
3810
0
     identifier );
3811
3812
0
    return( -1 );
3813
0
  }
3814
0
  else if( result != 0 )
3815
0
  {
3816
0
    if( libfvalue_value_get_data(
3817
0
         value,
3818
0
         &value_data,
3819
0
         &value_data_size,
3820
0
         &encoding,
3821
0
         error ) != 1 )
3822
0
    {
3823
0
      libcerror_error_set(
3824
0
       error,
3825
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3826
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3827
0
       "%s: unable to retrieve value data.",
3828
0
       function );
3829
3830
0
      return( -1 );
3831
0
    }
3832
0
    if( value_data == NULL )
3833
0
    {
3834
0
      libcerror_error_set(
3835
0
       error,
3836
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3837
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3838
0
       "%s: missing value data.",
3839
0
       function );
3840
3841
0
      return( -1 );
3842
0
    }
3843
0
    if( value_data_size == 6 )
3844
0
    {
3845
0
      if( narrow_string_compare(
3846
0
           "fixed",
3847
0
           value_data,
3848
0
           5 ) == 0 )
3849
0
      {
3850
0
        *media_type = LIBSMRAW_MEDIA_TYPE_FIXED;
3851
0
      }
3852
0
    }
3853
0
    else if( value_data_size == 7 )
3854
0
    {
3855
0
      if( narrow_string_compare(
3856
0
           "memory",
3857
0
           value_data,
3858
0
           6 ) == 0 )
3859
0
      {
3860
0
        *media_type = LIBSMRAW_MEDIA_TYPE_MEMORY;
3861
0
      }
3862
0
    }
3863
0
    else if( value_data_size == 8 )
3864
0
    {
3865
0
      if( narrow_string_compare(
3866
0
           "optical",
3867
0
           value_data,
3868
0
           7 ) == 0 )
3869
0
      {
3870
0
        *media_type = LIBSMRAW_MEDIA_TYPE_OPTICAL;
3871
0
      }
3872
0
    }
3873
0
    else if( value_data_size == 10 )
3874
0
    {
3875
0
      if( narrow_string_compare(
3876
0
           "removable",
3877
0
           value_data,
3878
0
           9 ) == 0 )
3879
0
      {
3880
0
        *media_type = LIBSMRAW_MEDIA_TYPE_REMOVABLE;
3881
0
      }
3882
0
    }
3883
0
  }
3884
0
  return( 1 );
3885
0
}
3886
3887
/* Sets the media type
3888
 * Returns the 1 if succesful or -1 on error
3889
 */
3890
int libsmraw_handle_set_media_type(
3891
     libsmraw_handle_t *handle,
3892
     uint8_t media_type,
3893
     libcerror_error_t **error )
3894
0
{
3895
0
  libsmraw_internal_handle_t *internal_handle = NULL;
3896
0
  libfvalue_value_t *value                    = NULL;
3897
0
  static char *function                       = "libsmraw_handle_set_media_type";
3898
0
  const char *identifier                      = "media_type";
3899
0
  const char *value_string                    = NULL;
3900
0
  size_t identifier_size                      = 10;
3901
0
  size_t value_string_length                  = 0;
3902
0
  int result                                  = 0;
3903
3904
0
  if( handle == NULL )
3905
0
  {
3906
0
    libcerror_error_set(
3907
0
     error,
3908
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3909
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3910
0
     "%s: invalid handle.",
3911
0
     function );
3912
3913
0
    return( -1 );
3914
0
  }
3915
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
3916
3917
0
  if( ( internal_handle->read_values_initialized != 0 )
3918
0
   || ( internal_handle->write_values_initialized != 0 ) )
3919
0
  {
3920
0
    libcerror_error_set(
3921
0
     error,
3922
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3923
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3924
0
     "%s: media values cannot be changed.",
3925
0
     function );
3926
3927
0
    return( -1 );
3928
0
  }
3929
/* TODO add thread-safety support */
3930
0
  switch( media_type )
3931
0
  {
3932
0
    case LIBSMRAW_MEDIA_TYPE_FIXED:
3933
0
      value_string        = "fixed";
3934
0
      value_string_length = 5;
3935
3936
0
      break;
3937
3938
0
    case LIBSMRAW_MEDIA_TYPE_MEMORY:
3939
0
      value_string        = "memory";
3940
0
      value_string_length = 6;
3941
3942
0
      break;
3943
3944
0
    case LIBSMRAW_MEDIA_TYPE_OPTICAL:
3945
0
      value_string        = "optical";
3946
0
      value_string_length = 7;
3947
3948
0
      break;
3949
3950
0
    case LIBSMRAW_MEDIA_TYPE_REMOVABLE:
3951
0
      value_string        = "removable";
3952
0
      value_string_length = 9;
3953
3954
0
      break;
3955
3956
0
    default:
3957
0
      libcerror_error_set(
3958
0
       error,
3959
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3960
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3961
0
       "%s: unsupported media type: 0x%02x.",
3962
0
       function,
3963
0
       media_type );
3964
3965
0
      return( -1 );
3966
0
  }
3967
0
  result = libfvalue_table_get_value_by_identifier(
3968
0
            internal_handle->media_values,
3969
0
            (uint8_t *) identifier,
3970
0
            identifier_size,
3971
0
            &value,
3972
0
            0,
3973
0
            error );
3974
3975
0
  if( result == -1 )
3976
0
  {
3977
0
    libcerror_error_set(
3978
0
     error,
3979
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3980
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3981
0
     "%s: unable to retrieve value: %s from media values table.",
3982
0
     function,
3983
0
     identifier );
3984
3985
0
    return( -1 );
3986
0
  }
3987
0
  else if( result == 0 )
3988
0
  {
3989
0
    if( libfvalue_value_type_initialize(
3990
0
         &value,
3991
0
         LIBFVALUE_VALUE_TYPE_STRING_UTF8,
3992
0
         error ) != 1 )
3993
0
    {
3994
0
      libcerror_error_set(
3995
0
       error,
3996
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3997
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3998
0
       "%s: unable to create value.",
3999
0
       function );
4000
4001
0
      return( -1 );
4002
0
    }
4003
0
    if( libfvalue_value_set_identifier(
4004
0
         value,
4005
0
         (uint8_t *) identifier,
4006
0
         identifier_size,
4007
0
         LIBFVALUE_VALUE_IDENTIFIER_FLAG_MANAGED,
4008
0
         error ) != 1 )
4009
0
    {
4010
0
      libcerror_error_set(
4011
0
       error,
4012
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4013
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4014
0
       "%s: unable to set identifier in value.",
4015
0
       function );
4016
4017
0
      libfvalue_value_free(
4018
0
       &value,
4019
0
       NULL );
4020
4021
0
      return( -1 );
4022
0
    }
4023
0
    if( libfvalue_table_set_value(
4024
0
         internal_handle->media_values,
4025
0
         value,
4026
0
         error ) != 1 )
4027
0
    {
4028
0
      libcerror_error_set(
4029
0
       error,
4030
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4031
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4032
0
       "%s: unable to set value: %s in media values table.",
4033
0
       function,
4034
0
       identifier );
4035
4036
0
      libfvalue_value_free(
4037
0
       &value,
4038
0
       NULL );
4039
4040
0
      return( -1 );
4041
0
    }
4042
0
  }
4043
0
  if( libfvalue_value_copy_from_utf8_string(
4044
0
       value,
4045
0
       0,
4046
0
       (uint8_t *) value_string,
4047
0
       value_string_length,
4048
0
       error ) != 1 )
4049
0
  {
4050
0
    libcerror_error_set(
4051
0
     error,
4052
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4053
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
4054
0
     "%s: unable to copy value from an UTF-8 string.",
4055
0
     function );
4056
4057
0
    return( -1 );
4058
0
  }
4059
0
  return( 1 );
4060
0
}
4061
4062
/* Retrieves the media flags
4063
 * Returns the 1 if succesful or -1 on error
4064
 */
4065
int libsmraw_handle_get_media_flags(
4066
     libsmraw_handle_t *handle,
4067
     uint8_t *media_flags,
4068
     libcerror_error_t **error )
4069
0
{
4070
0
  libsmraw_internal_handle_t *internal_handle = NULL;
4071
0
  libfvalue_value_t *value                    = NULL;
4072
0
  uint8_t *value_data                         = NULL;
4073
0
  static char *function                       = "libsmraw_handle_get_media_flags";
4074
0
  const char *identifier                      = "media_flags";
4075
0
  size_t identifier_size                      = 11;
4076
0
  size_t value_data_size                      = 0;
4077
0
  int encoding                                = 0;
4078
0
  int result                                  = 0;
4079
4080
0
  if( handle == NULL )
4081
0
  {
4082
0
    libcerror_error_set(
4083
0
     error,
4084
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4085
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4086
0
     "%s: invalid handle.",
4087
0
     function );
4088
4089
0
    return( -1 );
4090
0
  }
4091
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
4092
4093
0
  if( internal_handle->file_io_pool == NULL )
4094
0
  {
4095
0
    libcerror_error_set(
4096
0
     error,
4097
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4098
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4099
0
     "%s: invalid handle - missing file io pool.",
4100
0
     function );
4101
4102
0
    return( -1 );
4103
0
  }
4104
0
  if( media_flags == NULL )
4105
0
  {
4106
0
    libcerror_error_set(
4107
0
     error,
4108
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4109
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4110
0
     "%s: invalid media flags.",
4111
0
     function );
4112
4113
0
    return( -1 );
4114
0
  }
4115
/* TODO add thread-safety support */
4116
0
  result = libfvalue_table_get_value_by_identifier(
4117
0
            internal_handle->media_values,
4118
0
            (uint8_t *) identifier,
4119
0
            identifier_size,
4120
0
            &value,
4121
0
            0,
4122
0
            error );
4123
4124
0
  if( result == -1 )
4125
0
  {
4126
0
    libcerror_error_set(
4127
0
     error,
4128
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4129
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4130
0
     "%s: unable to retrieve value: %s from media values table.",
4131
0
     function,
4132
0
     identifier );
4133
4134
0
    return( -1 );
4135
0
  }
4136
0
  else if( result != 0 )
4137
0
  {
4138
0
    if( libfvalue_value_get_data(
4139
0
         value,
4140
0
         &value_data,
4141
0
         &value_data_size,
4142
0
         &encoding,
4143
0
         error ) != 1 )
4144
0
    {
4145
0
      libcerror_error_set(
4146
0
       error,
4147
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4148
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4149
0
       "%s: unable to retrieve value data.",
4150
0
       function );
4151
4152
0
      return( -1 );
4153
0
    }
4154
0
    if( value_data == NULL )
4155
0
    {
4156
0
      libcerror_error_set(
4157
0
       error,
4158
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4159
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4160
0
       "%s: missing value data.",
4161
0
       function );
4162
4163
0
      return( -1 );
4164
0
    }
4165
0
    if( value_data_size == 8 )
4166
0
    {
4167
0
      if( narrow_string_compare(
4168
0
           "logical",
4169
0
           value_data,
4170
0
           7 ) == 0 )
4171
0
      {
4172
0
        *media_flags &= ~( LIBSMRAW_MEDIA_FLAG_PHYSICAL );
4173
0
      }
4174
0
    }
4175
0
    else if( value_data_size == 9 )
4176
0
    {
4177
0
      if( narrow_string_compare(
4178
0
           "physical",
4179
0
           value_data,
4180
0
           8 ) == 0 )
4181
0
      {
4182
0
        *media_flags |= LIBSMRAW_MEDIA_FLAG_PHYSICAL;
4183
0
      }
4184
0
    }
4185
0
  }
4186
0
  return( 1 );
4187
0
}
4188
4189
/* Sets the media flags
4190
 * Returns the 1 if succesful or -1 on error
4191
 */
4192
int libsmraw_handle_set_media_flags(
4193
     libsmraw_handle_t *handle,
4194
     uint8_t media_flags,
4195
     libcerror_error_t **error )
4196
0
{
4197
0
  libsmraw_internal_handle_t *internal_handle = NULL;
4198
0
  libfvalue_value_t *value                    = NULL;
4199
0
  static char *function                       = "libsmraw_handle_set_media_flags";
4200
0
  const char *identifier                      = "media_flags";
4201
0
  const char *value_string                    = NULL;
4202
0
  size_t identifier_size                      = 11;
4203
0
  size_t value_string_length                  = 0;
4204
0
  int result                                  = 0;
4205
4206
0
  if( handle == NULL )
4207
0
  {
4208
0
    libcerror_error_set(
4209
0
     error,
4210
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4211
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4212
0
     "%s: invalid handle.",
4213
0
     function );
4214
4215
0
    return( -1 );
4216
0
  }
4217
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
4218
4219
0
  if( ( internal_handle->read_values_initialized != 0 )
4220
0
   || ( internal_handle->write_values_initialized != 0 ) )
4221
0
  {
4222
0
    libcerror_error_set(
4223
0
     error,
4224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4225
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4226
0
     "%s: media size cannot be changed.",
4227
0
     function );
4228
4229
0
    return( -1 );
4230
0
  }
4231
0
  if( ( media_flags & ~( LIBSMRAW_MEDIA_FLAG_PHYSICAL ) ) != 0 )
4232
0
  {
4233
0
    libcerror_error_set(
4234
0
     error,
4235
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4236
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
4237
0
     "%s: unsupported media flags: 0x%02x.",
4238
0
     function,
4239
0
     media_flags );
4240
4241
0
    return( -1 );
4242
0
  }
4243
/* TODO add thread-safety support */
4244
0
  if( ( media_flags & LIBSMRAW_MEDIA_FLAG_PHYSICAL ) != 0 )
4245
0
  {
4246
0
    value_string        = "physical";
4247
0
    value_string_length = 8;
4248
0
  }
4249
0
  else
4250
0
  {
4251
0
    value_string        = "logical";
4252
0
    value_string_length = 7;
4253
0
  }
4254
0
  result = libfvalue_table_get_value_by_identifier(
4255
0
            internal_handle->media_values,
4256
0
            (uint8_t *) identifier,
4257
0
            identifier_size,
4258
0
            &value,
4259
0
            0,
4260
0
            error );
4261
4262
0
  if( result == -1 )
4263
0
  {
4264
0
    libcerror_error_set(
4265
0
     error,
4266
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4267
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4268
0
     "%s: unable to retrieve value: %s from media values table.",
4269
0
     function,
4270
0
     identifier );
4271
4272
0
    return( -1 );
4273
0
  }
4274
0
  else if( result == 0 )
4275
0
  {
4276
0
    if( libfvalue_value_type_initialize(
4277
0
         &value,
4278
0
         LIBFVALUE_VALUE_TYPE_STRING_UTF8,
4279
0
         error ) != 1 )
4280
0
    {
4281
0
      libcerror_error_set(
4282
0
       error,
4283
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4284
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4285
0
       "%s: unable to create value.",
4286
0
       function );
4287
4288
0
      return( -1 );
4289
0
    }
4290
0
    if( libfvalue_value_set_identifier(
4291
0
         value,
4292
0
         (uint8_t *) identifier,
4293
0
         identifier_size,
4294
0
         LIBFVALUE_VALUE_IDENTIFIER_FLAG_MANAGED,
4295
0
         error ) != 1 )
4296
0
    {
4297
0
      libcerror_error_set(
4298
0
       error,
4299
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4300
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4301
0
       "%s: unable to set identifier in value.",
4302
0
       function );
4303
4304
0
      libfvalue_value_free(
4305
0
       &value,
4306
0
       NULL );
4307
4308
0
      return( -1 );
4309
0
    }
4310
0
    if( libfvalue_table_set_value(
4311
0
         internal_handle->media_values,
4312
0
         value,
4313
0
         error ) != 1 )
4314
0
    {
4315
0
      libcerror_error_set(
4316
0
       error,
4317
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4318
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4319
0
       "%s: unable to set value: %s in media values table.",
4320
0
       function,
4321
0
       identifier );
4322
4323
0
      libfvalue_value_free(
4324
0
       &value,
4325
0
       NULL );
4326
4327
0
      return( -1 );
4328
0
    }
4329
0
  }
4330
0
  if( libfvalue_value_copy_from_utf8_string(
4331
0
       value,
4332
0
       0,
4333
0
       (uint8_t *) value_string,
4334
0
       value_string_length,
4335
0
       error ) != 1 )
4336
0
  {
4337
0
    libcerror_error_set(
4338
0
     error,
4339
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4340
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
4341
0
     "%s: unable to copy value from an UTF-8 string.",
4342
0
     function );
4343
4344
0
    return( -1 );
4345
0
  }
4346
0
  return( 1 );
4347
0
}
4348
4349
/* Retrieves the number of information values
4350
 * Returns 1 if successful or -1 on error
4351
 */
4352
int libsmraw_handle_get_number_of_information_values(
4353
     libsmraw_handle_t *handle,
4354
     int *number_of_information_values,
4355
     libcerror_error_t **error )
4356
0
{
4357
0
  libsmraw_internal_handle_t *internal_handle = NULL;
4358
0
  static char *function                       = "libsmraw_handle_get_number_of_information_values";
4359
4360
0
  if( handle == NULL )
4361
0
  {
4362
0
    libcerror_error_set(
4363
0
     error,
4364
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4365
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4366
0
     "%s: invalid handle.",
4367
0
     function );
4368
4369
0
    return( -1 );
4370
0
  }
4371
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
4372
4373
0
  if( internal_handle->file_io_pool == NULL )
4374
0
  {
4375
0
    libcerror_error_set(
4376
0
     error,
4377
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4378
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4379
0
     "%s: invalid handle - missing file io pool.",
4380
0
     function );
4381
4382
0
    return( -1 );
4383
0
  }
4384
/* TODO add thread-safety support */
4385
0
  if( libfvalue_table_get_number_of_values(
4386
0
       internal_handle->information_values,
4387
0
       number_of_information_values,
4388
0
       error ) != 1 )
4389
0
  {
4390
0
    libcerror_error_set(
4391
0
     error,
4392
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4393
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4394
0
     "%s: unable to retrieve number of information values.",
4395
0
     function );
4396
4397
0
    return( -1 );
4398
0
  }
4399
0
  return( 1 );
4400
0
}
4401
4402
/* Retrieves the size of a specific information value identifier
4403
 * The identifier size includes the end of string character
4404
 * Returns 1 if successful or -1 on error
4405
 */
4406
int libsmraw_handle_get_information_value_identifier_size(
4407
     libsmraw_handle_t *handle,
4408
     int information_value_index,
4409
     size_t *identifier_size,
4410
     libcerror_error_t **error )
4411
0
{
4412
0
  libsmraw_internal_handle_t *internal_handle = NULL;
4413
0
  libfvalue_value_t *value                    = NULL;
4414
0
  uint8_t *value_identifier                   = NULL;
4415
0
  static char *function                       = "libsmraw_handle_get_information_value_identifier_size";
4416
4417
0
  if( handle == NULL )
4418
0
  {
4419
0
    libcerror_error_set(
4420
0
     error,
4421
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4422
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4423
0
     "%s: invalid handle.",
4424
0
     function );
4425
4426
0
    return( -1 );
4427
0
  }
4428
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
4429
4430
0
  if( internal_handle->file_io_pool == NULL )
4431
0
  {
4432
0
    libcerror_error_set(
4433
0
     error,
4434
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4435
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4436
0
     "%s: invalid handle - missing file io pool.",
4437
0
     function );
4438
4439
0
    return( -1 );
4440
0
  }
4441
/* TODO add thread-safety support */
4442
0
  if( libfvalue_table_get_value_by_index(
4443
0
       internal_handle->information_values,
4444
0
       information_value_index,
4445
0
       &value,
4446
0
       error ) != 1 )
4447
0
  {
4448
0
    libcerror_error_set(
4449
0
     error,
4450
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4451
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4452
0
     "%s: unable to retrieve value: %d from information values table.",
4453
0
     function,
4454
0
     information_value_index );
4455
4456
0
    return( -1 );
4457
0
  }
4458
0
  if( libfvalue_value_get_identifier(
4459
0
       value,
4460
0
       &value_identifier,
4461
0
       identifier_size,
4462
0
       error ) != 1 )
4463
0
  {
4464
0
    libcerror_error_set(
4465
0
     error,
4466
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4467
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4468
0
     "%s: unable to retrieve value identifier: %d.",
4469
0
     function,
4470
0
     information_value_index );
4471
4472
0
    return( -1 );
4473
0
  }
4474
0
  if( value_identifier == NULL )
4475
0
  {
4476
0
    libcerror_error_set(
4477
0
     error,
4478
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4479
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4480
0
     "%s: missing value identifier: %d.",
4481
0
     function,
4482
0
     information_value_index );
4483
4484
0
    return( -1 );
4485
0
  }
4486
0
  return( 1 );
4487
0
}
4488
4489
/* Retrieves a specific information value identifier
4490
 * The identifier size should include the end of string character
4491
 * Returns 1 if successful or -1 on error
4492
 */
4493
int libsmraw_handle_get_information_value_identifier(
4494
     libsmraw_handle_t *handle,
4495
     int information_value_index,
4496
     uint8_t *identifier,
4497
     size_t identifier_size,
4498
     libcerror_error_t **error )
4499
0
{
4500
0
  libsmraw_internal_handle_t *internal_handle = NULL;
4501
0
  libfvalue_value_t *value                    = NULL;
4502
0
  uint8_t *value_identifier                   = NULL;
4503
0
  static char *function                       = "libsmraw_handle_get_information_value_identifier";
4504
0
  size_t value_identifier_size                = 0;
4505
4506
0
  if( handle == NULL )
4507
0
  {
4508
0
    libcerror_error_set(
4509
0
     error,
4510
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4511
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4512
0
     "%s: invalid handle.",
4513
0
     function );
4514
4515
0
    return( -1 );
4516
0
  }
4517
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
4518
4519
0
  if( internal_handle->file_io_pool == NULL )
4520
0
  {
4521
0
    libcerror_error_set(
4522
0
     error,
4523
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4524
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4525
0
     "%s: invalid handle - missing file io pool.",
4526
0
     function );
4527
4528
0
    return( -1 );
4529
0
  }
4530
/* TODO add thread-safety support */
4531
0
  if( libfvalue_table_get_value_by_index(
4532
0
       internal_handle->information_values,
4533
0
       information_value_index,
4534
0
       &value,
4535
0
       error ) != 1 )
4536
0
  {
4537
0
    libcerror_error_set(
4538
0
     error,
4539
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4540
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4541
0
     "%s: unable to retrieve value: %d from information values table.",
4542
0
     function,
4543
0
     information_value_index );
4544
4545
0
    return( -1 );
4546
0
  }
4547
0
  if( libfvalue_value_get_identifier(
4548
0
       value,
4549
0
       &value_identifier,
4550
0
       &value_identifier_size,
4551
0
       error ) != 1 )
4552
0
  {
4553
0
    libcerror_error_set(
4554
0
     error,
4555
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4556
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4557
0
     "%s: unable to retrieve value identifier: %d.",
4558
0
     function,
4559
0
     information_value_index );
4560
4561
0
    return( -1 );
4562
0
  }
4563
0
  if( value_identifier == NULL )
4564
0
  {
4565
0
    libcerror_error_set(
4566
0
     error,
4567
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4568
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4569
0
     "%s: missing value identifier: %d.",
4570
0
     function,
4571
0
     information_value_index );
4572
4573
0
    return( -1 );
4574
0
  }
4575
0
  if( identifier_size < value_identifier_size )
4576
0
  {
4577
0
    libcerror_error_set(
4578
0
     error,
4579
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4580
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
4581
0
     "%s: identifier too small.",
4582
0
     function );
4583
4584
0
    return( -1 );
4585
0
  }
4586
0
  if( memory_copy(
4587
0
       identifier,
4588
0
       value_identifier,
4589
0
       value_identifier_size ) == NULL )
4590
0
  {
4591
0
    libcerror_error_set(
4592
0
     error,
4593
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
4594
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
4595
0
     "%s: unable to copy identifier.",
4596
0
     function );
4597
4598
0
    return( -1 );
4599
0
  }
4600
0
  return( 1 );
4601
0
}
4602
4603
/* Retrieves the size of an UTF-8 encoded information value for the specific identifier
4604
 * The value size includes the end of string character
4605
 * Returns 1 if successful, 0 if value not present or -1 on error
4606
 */
4607
int libsmraw_handle_get_utf8_information_value_size(
4608
     libsmraw_handle_t *handle,
4609
     const uint8_t *identifier,
4610
     size_t identifier_length,
4611
     size_t *utf8_string_size,
4612
     libcerror_error_t **error )
4613
0
{
4614
0
  libsmraw_internal_handle_t *internal_handle = NULL;
4615
0
  libfvalue_value_t *value                    = NULL;
4616
0
  static char *function                       = "libsmraw_handle_get_utf8_information_value_size";
4617
0
  int result                                  = 0;
4618
4619
0
  if( handle == NULL )
4620
0
  {
4621
0
    libcerror_error_set(
4622
0
     error,
4623
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4624
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4625
0
     "%s: invalid handle.",
4626
0
     function );
4627
4628
0
    return( -1 );
4629
0
  }
4630
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
4631
4632
0
  if( internal_handle->file_io_pool == NULL )
4633
0
  {
4634
0
    libcerror_error_set(
4635
0
     error,
4636
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4637
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4638
0
     "%s: invalid handle - missing file io pool.",
4639
0
     function );
4640
4641
0
    return( -1 );
4642
0
  }
4643
0
  if( identifier == NULL )
4644
0
  {
4645
0
    libcerror_error_set(
4646
0
     error,
4647
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4648
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4649
0
     "%s: invalid identifier.",
4650
0
     function );
4651
4652
0
    return( -1 );
4653
0
  }
4654
/* TODO add thread-safety support */
4655
0
  result = libfvalue_table_get_value_by_identifier(
4656
0
            internal_handle->information_values,
4657
0
            identifier,
4658
0
            identifier_length + 1,
4659
0
            &value,
4660
0
            0,
4661
0
            error );
4662
4663
0
  if( result == -1 )
4664
0
  {
4665
0
    libcerror_error_set(
4666
0
     error,
4667
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4668
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4669
0
     "%s: unable to retrieve value: %s from information values table.",
4670
0
     function,
4671
0
     (char *) identifier );
4672
4673
0
    return( -1 );
4674
0
  }
4675
0
  else if( result != 0 )
4676
0
  {
4677
0
    if( libfvalue_value_get_utf8_string_size(
4678
0
         value,
4679
0
         0,
4680
0
         utf8_string_size,
4681
0
         error ) != 1 )
4682
0
    {
4683
0
      libcerror_error_set(
4684
0
       error,
4685
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4686
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4687
0
       "%s: unable to retrieve value: %s UTF-8 string size.",
4688
0
       function,
4689
0
       (char *) identifier );
4690
4691
0
      return( -1 );
4692
0
    }
4693
0
  }
4694
0
  return( result );
4695
0
}
4696
4697
/* Retrieves an UTF-8 encoded information value for the specific identifier
4698
 * The value size should include the end of string character
4699
 * Returns 1 if successful, 0 if value not present or -1 on error
4700
 */
4701
int libsmraw_handle_get_utf8_information_value(
4702
     libsmraw_handle_t *handle,
4703
     const uint8_t *identifier,
4704
     size_t identifier_length,
4705
     uint8_t *utf8_string,
4706
     size_t utf8_string_size,
4707
     libcerror_error_t **error )
4708
0
{
4709
0
  libsmraw_internal_handle_t *internal_handle = NULL;
4710
0
  libfvalue_value_t *value                    = NULL;
4711
0
  static char *function                       = "libsmraw_handle_get_utf8_information_value";
4712
0
  int result                                  = 0;
4713
4714
0
  if( handle == NULL )
4715
0
  {
4716
0
    libcerror_error_set(
4717
0
     error,
4718
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4719
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4720
0
     "%s: invalid handle.",
4721
0
     function );
4722
4723
0
    return( -1 );
4724
0
  }
4725
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
4726
4727
0
  if( internal_handle->file_io_pool == NULL )
4728
0
  {
4729
0
    libcerror_error_set(
4730
0
     error,
4731
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4732
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4733
0
     "%s: invalid handle - missing file io pool.",
4734
0
     function );
4735
4736
0
    return( -1 );
4737
0
  }
4738
0
  if( identifier == NULL )
4739
0
  {
4740
0
    libcerror_error_set(
4741
0
     error,
4742
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4743
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4744
0
     "%s: invalid identifier.",
4745
0
     function );
4746
4747
0
    return( -1 );
4748
0
  }
4749
/* TODO add thread-safety support */
4750
0
  result = libfvalue_table_get_value_by_identifier(
4751
0
            internal_handle->information_values,
4752
0
            identifier,
4753
0
            identifier_length + 1,
4754
0
            &value,
4755
0
            0,
4756
0
            error );
4757
4758
0
  if( result == -1 )
4759
0
  {
4760
0
    libcerror_error_set(
4761
0
     error,
4762
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4763
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4764
0
     "%s: unable to retrieve value: %s from information values table.",
4765
0
     function,
4766
0
     (char *) identifier );
4767
4768
0
    return( -1 );
4769
0
  }
4770
0
  else if( result != 0 )
4771
0
  {
4772
0
    if( libfvalue_value_copy_to_utf8_string(
4773
0
         value,
4774
0
         0,
4775
0
         utf8_string,
4776
0
         utf8_string_size,
4777
0
         error ) != 1 )
4778
0
    {
4779
0
      libcerror_error_set(
4780
0
       error,
4781
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4782
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
4783
0
       "%s: unable to copy value: %s to an UTF-8 string.",
4784
0
       function,
4785
0
       (char *) identifier );
4786
4787
0
      return( -1 );
4788
0
    }
4789
0
  }
4790
0
  return( result );
4791
0
}
4792
4793
/* Sets an UTF-8 encoded information value for the specific identifier
4794
 * Returns the 1 if succesful or -1 on error
4795
 */
4796
int libsmraw_handle_set_utf8_information_value(
4797
     libsmraw_handle_t *handle,
4798
     const uint8_t *identifier,
4799
     size_t identifier_length,
4800
     const uint8_t *utf8_string,
4801
     size_t utf8_string_length,
4802
     libcerror_error_t **error )
4803
0
{
4804
0
  libsmraw_internal_handle_t *internal_handle = NULL;
4805
0
  libfvalue_value_t *value                    = NULL;
4806
0
  static char *function                       = "libsmraw_handle_set_utf8_information_value";
4807
0
  int result                                  = 0;
4808
4809
0
  if( handle == NULL )
4810
0
  {
4811
0
    libcerror_error_set(
4812
0
     error,
4813
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4814
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4815
0
     "%s: invalid handle.",
4816
0
     function );
4817
4818
0
    return( -1 );
4819
0
  }
4820
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
4821
4822
0
  if( internal_handle->read_values_initialized != 0 )
4823
0
  {
4824
0
    libcerror_error_set(
4825
0
     error,
4826
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4827
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4828
0
     "%s: information values cannot be changed.",
4829
0
     function );
4830
4831
0
    return( -1 );
4832
0
  }
4833
0
  if( identifier == NULL )
4834
0
  {
4835
0
    libcerror_error_set(
4836
0
     error,
4837
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4838
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4839
0
     "%s: invalid identifier.",
4840
0
     function );
4841
4842
0
    return( -1 );
4843
0
  }
4844
/* TODO add thread-safety support */
4845
0
  result = libfvalue_table_get_value_by_identifier(
4846
0
            internal_handle->information_values,
4847
0
            identifier,
4848
0
            identifier_length + 1,
4849
0
            &value,
4850
0
            0,
4851
0
            error );
4852
4853
0
  if( result == -1 )
4854
0
  {
4855
0
    libcerror_error_set(
4856
0
     error,
4857
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4858
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4859
0
     "%s: unable to retrieve value: %s from information values table.",
4860
0
     function,
4861
0
     (char *) identifier );
4862
4863
0
    return( -1 );
4864
0
  }
4865
0
  else if( result == 0 )
4866
0
  {
4867
0
    if( libfvalue_value_type_initialize(
4868
0
         &value,
4869
0
         LIBFVALUE_VALUE_TYPE_STRING_UTF8,
4870
0
         error ) != 1 )
4871
0
    {
4872
0
      libcerror_error_set(
4873
0
       error,
4874
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4875
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4876
0
       "%s: unable to create value.",
4877
0
       function );
4878
4879
0
      return( -1 );
4880
0
    }
4881
0
    if( libfvalue_value_set_identifier(
4882
0
         value,
4883
0
         identifier,
4884
0
         identifier_length + 1,
4885
0
         LIBFVALUE_VALUE_IDENTIFIER_FLAG_MANAGED,
4886
0
         error ) != 1 )
4887
0
    {
4888
0
      libcerror_error_set(
4889
0
       error,
4890
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4891
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4892
0
       "%s: unable to set identifier in value.",
4893
0
       function );
4894
4895
0
      libfvalue_value_free(
4896
0
       &value,
4897
0
       NULL );
4898
4899
0
      return( -1 );
4900
0
    }
4901
0
    if( libfvalue_table_set_value(
4902
0
         internal_handle->information_values,
4903
0
         value,
4904
0
         error ) != 1 )
4905
0
    {
4906
0
      libcerror_error_set(
4907
0
       error,
4908
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4909
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4910
0
       "%s: unable to set value: %s in information values table.",
4911
0
       function,
4912
0
       (char *) identifier );
4913
4914
0
      libfvalue_value_free(
4915
0
       &value,
4916
0
       NULL );
4917
4918
0
      return( -1 );
4919
0
    }
4920
0
  }
4921
0
  if( libfvalue_value_copy_from_utf8_string(
4922
0
       value,
4923
0
       0,
4924
0
       utf8_string,
4925
0
       utf8_string_length + 1,
4926
0
       error ) != 1 )
4927
0
  {
4928
0
    libcerror_error_set(
4929
0
     error,
4930
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4931
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
4932
0
     "%s: unable to copy value: %s from an UTF-8 string.",
4933
0
     function,
4934
0
     (char *) identifier );
4935
4936
0
    return( -1 );
4937
0
  }
4938
0
  return( 1 );
4939
0
}
4940
4941
/* Retrieves the size of an UTF-16 encoded information value for the specific identifier
4942
 * The value size includes the end of string character
4943
 * Returns 1 if successful, 0 if value not present or -1 on error
4944
 */
4945
int libsmraw_handle_get_utf16_information_value_size(
4946
     libsmraw_handle_t *handle,
4947
     const uint8_t *identifier,
4948
     size_t identifier_length,
4949
     size_t *utf16_string_size,
4950
     libcerror_error_t **error )
4951
0
{
4952
0
  libsmraw_internal_handle_t *internal_handle = NULL;
4953
0
  libfvalue_value_t *value                    = NULL;
4954
0
  static char *function                       = "libsmraw_handle_get_utf16_information_value_size";
4955
0
  int result                                  = 0;
4956
4957
0
  if( handle == NULL )
4958
0
  {
4959
0
    libcerror_error_set(
4960
0
     error,
4961
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4962
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4963
0
     "%s: invalid handle.",
4964
0
     function );
4965
4966
0
    return( -1 );
4967
0
  }
4968
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
4969
4970
0
  if( internal_handle->file_io_pool == NULL )
4971
0
  {
4972
0
    libcerror_error_set(
4973
0
     error,
4974
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4975
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4976
0
     "%s: invalid handle - missing file io pool.",
4977
0
     function );
4978
4979
0
    return( -1 );
4980
0
  }
4981
0
  if( identifier == NULL )
4982
0
  {
4983
0
    libcerror_error_set(
4984
0
     error,
4985
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4986
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4987
0
     "%s: invalid identifier.",
4988
0
     function );
4989
4990
0
    return( -1 );
4991
0
  }
4992
/* TODO add thread-safety support */
4993
0
  result = libfvalue_table_get_value_by_identifier(
4994
0
            internal_handle->information_values,
4995
0
            identifier,
4996
0
            identifier_length + 1,
4997
0
            &value,
4998
0
            0,
4999
0
            error );
5000
5001
0
  if( result == -1 )
5002
0
  {
5003
0
    libcerror_error_set(
5004
0
     error,
5005
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5006
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5007
0
     "%s: unable to retrieve value: %s from information values table.",
5008
0
     function,
5009
0
     (char *) identifier );
5010
5011
0
    return( -1 );
5012
0
  }
5013
0
  else if( result != 0 )
5014
0
  {
5015
0
    if( libfvalue_value_get_utf16_string_size(
5016
0
         value,
5017
0
         0,
5018
0
         utf16_string_size,
5019
0
         error ) != 1 )
5020
0
    {
5021
0
      libcerror_error_set(
5022
0
       error,
5023
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5024
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5025
0
       "%s: unable to retrieve value: %s UTF-16 string size.",
5026
0
       function,
5027
0
       (char *) identifier );
5028
5029
0
      return( -1 );
5030
0
    }
5031
0
  }
5032
0
  return( result );
5033
0
}
5034
5035
/* Retrieves an UTF-16 encoded information value for the specific identifier
5036
 * The value size should include the end of string character
5037
 * Returns 1 if successful, 0 if value not present or -1 on error
5038
 */
5039
int libsmraw_handle_get_utf16_information_value(
5040
     libsmraw_handle_t *handle,
5041
     const uint8_t *identifier,
5042
     size_t identifier_length,
5043
     uint16_t *utf16_string,
5044
     size_t utf16_string_size,
5045
     libcerror_error_t **error )
5046
0
{
5047
0
  libsmraw_internal_handle_t *internal_handle = NULL;
5048
0
  libfvalue_value_t *value                    = NULL;
5049
0
  static char *function                       = "libsmraw_handle_get_utf16_information_value";
5050
0
  int result                                  = 0;
5051
5052
0
  if( handle == NULL )
5053
0
  {
5054
0
    libcerror_error_set(
5055
0
     error,
5056
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5057
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5058
0
     "%s: invalid handle.",
5059
0
     function );
5060
5061
0
    return( -1 );
5062
0
  }
5063
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
5064
5065
0
  if( internal_handle->file_io_pool == NULL )
5066
0
  {
5067
0
    libcerror_error_set(
5068
0
     error,
5069
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5070
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5071
0
     "%s: invalid handle - missing file io pool.",
5072
0
     function );
5073
5074
0
    return( -1 );
5075
0
  }
5076
0
  if( identifier == NULL )
5077
0
  {
5078
0
    libcerror_error_set(
5079
0
     error,
5080
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5081
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5082
0
     "%s: invalid identifier.",
5083
0
     function );
5084
5085
0
    return( -1 );
5086
0
  }
5087
/* TODO add thread-safety support */
5088
0
  result = libfvalue_table_get_value_by_identifier(
5089
0
            internal_handle->information_values,
5090
0
            identifier,
5091
0
            identifier_length + 1,
5092
0
            &value,
5093
0
            0,
5094
0
            error );
5095
5096
0
  if( result == -1 )
5097
0
  {
5098
0
    libcerror_error_set(
5099
0
     error,
5100
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5101
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5102
0
     "%s: unable to retrieve value: %s from information values table.",
5103
0
     function,
5104
0
     (char *) identifier );
5105
5106
0
    return( -1 );
5107
0
  }
5108
0
  else if( result != 0 )
5109
0
  {
5110
0
    if( libfvalue_value_copy_to_utf16_string(
5111
0
         value,
5112
0
         0,
5113
0
         utf16_string,
5114
0
         utf16_string_size,
5115
0
         error ) != 1 )
5116
0
    {
5117
0
      libcerror_error_set(
5118
0
       error,
5119
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5120
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
5121
0
       "%s: unable to copy value: %s to an UTF-16 string.",
5122
0
       function,
5123
0
       (char *) identifier );
5124
5125
0
      return( -1 );
5126
0
    }
5127
0
  }
5128
0
  return( result );
5129
0
}
5130
5131
/* Sets an UTF-16 encoded information value for the specific identifier
5132
 * Returns the 1 if succesful or -1 on error
5133
 */
5134
int libsmraw_handle_set_utf16_information_value(
5135
     libsmraw_handle_t *handle,
5136
     const uint8_t *identifier,
5137
     size_t identifier_length,
5138
     const uint16_t *utf16_string,
5139
     size_t utf16_string_length,
5140
     libcerror_error_t **error )
5141
0
{
5142
0
  libsmraw_internal_handle_t *internal_handle = NULL;
5143
0
  libfvalue_value_t *value                    = NULL;
5144
0
  static char *function                       = "libsmraw_handle_set_utf16_information_value";
5145
0
  int result                                  = 0;
5146
5147
0
  if( handle == NULL )
5148
0
  {
5149
0
    libcerror_error_set(
5150
0
     error,
5151
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5152
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5153
0
     "%s: invalid handle.",
5154
0
     function );
5155
5156
0
    return( -1 );
5157
0
  }
5158
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
5159
5160
0
  if( internal_handle->read_values_initialized != 0 )
5161
0
  {
5162
0
    libcerror_error_set(
5163
0
     error,
5164
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5165
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5166
0
     "%s: information values cannot be changed.",
5167
0
     function );
5168
5169
0
    return( -1 );
5170
0
  }
5171
0
  if( identifier == NULL )
5172
0
  {
5173
0
    libcerror_error_set(
5174
0
     error,
5175
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5176
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5177
0
     "%s: invalid identifier.",
5178
0
     function );
5179
5180
0
    return( -1 );
5181
0
  }
5182
/* TODO add thread-safety support */
5183
0
  result = libfvalue_table_get_value_by_identifier(
5184
0
            internal_handle->information_values,
5185
0
            identifier,
5186
0
            identifier_length + 1,
5187
0
            &value,
5188
0
            0,
5189
0
            error );
5190
5191
0
  if( result == -1 )
5192
0
  {
5193
0
    libcerror_error_set(
5194
0
     error,
5195
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5196
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5197
0
     "%s: unable to retrieve value: %s from information values table.",
5198
0
     function,
5199
0
     (char *) identifier );
5200
5201
0
    return( -1 );
5202
0
  }
5203
0
  else if( result == 0 )
5204
0
  {
5205
0
    if( libfvalue_value_type_initialize(
5206
0
         &value,
5207
0
         LIBFVALUE_VALUE_TYPE_STRING_UTF8,
5208
0
         error ) != 1 )
5209
0
    {
5210
0
      libcerror_error_set(
5211
0
       error,
5212
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5213
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5214
0
       "%s: unable to create value.",
5215
0
       function );
5216
5217
0
      return( -1 );
5218
0
    }
5219
0
    if( libfvalue_value_set_identifier(
5220
0
         value,
5221
0
         identifier,
5222
0
         identifier_length + 1,
5223
0
         LIBFVALUE_VALUE_IDENTIFIER_FLAG_MANAGED,
5224
0
         error ) != 1 )
5225
0
    {
5226
0
      libcerror_error_set(
5227
0
       error,
5228
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5229
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5230
0
       "%s: unable to set identifier in value.",
5231
0
       function );
5232
5233
0
      libfvalue_value_free(
5234
0
       &value,
5235
0
       NULL );
5236
5237
0
      return( -1 );
5238
0
    }
5239
0
    if( libfvalue_table_set_value(
5240
0
         internal_handle->information_values,
5241
0
         value,
5242
0
         error ) != 1 )
5243
0
    {
5244
0
      libcerror_error_set(
5245
0
       error,
5246
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5247
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5248
0
       "%s: unable to set value: %s in information values table.",
5249
0
       function,
5250
0
       (char *) identifier );
5251
5252
0
      libfvalue_value_free(
5253
0
       &value,
5254
0
       NULL );
5255
5256
0
      return( -1 );
5257
0
    }
5258
0
  }
5259
0
  if( libfvalue_value_copy_from_utf16_string(
5260
0
       value,
5261
0
       0,
5262
0
       utf16_string,
5263
0
       utf16_string_length + 1,
5264
0
       error ) != 1 )
5265
0
  {
5266
0
    libcerror_error_set(
5267
0
     error,
5268
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5269
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
5270
0
     "%s: unable to copy value: %s from an UTF-16 string.",
5271
0
     function,
5272
0
     (char *) identifier );
5273
5274
0
    return( -1 );
5275
0
  }
5276
0
  return( 1 );
5277
0
}
5278
5279
/* Retrieves the number of integrity hash values
5280
 * Returns 1 if successful or -1 on error
5281
 */
5282
int libsmraw_handle_get_number_of_integrity_hash_values(
5283
     libsmraw_handle_t *handle,
5284
     int *number_of_integrity_hash_values,
5285
     libcerror_error_t **error )
5286
0
{
5287
0
  libsmraw_internal_handle_t *internal_handle = NULL;
5288
0
  static char *function                       = "libsmraw_handle_get_number_of_integrity_hash_values";
5289
5290
0
  if( handle == NULL )
5291
0
  {
5292
0
    libcerror_error_set(
5293
0
     error,
5294
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5295
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5296
0
     "%s: invalid handle.",
5297
0
     function );
5298
5299
0
    return( -1 );
5300
0
  }
5301
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
5302
5303
0
  if( internal_handle->file_io_pool == NULL )
5304
0
  {
5305
0
    libcerror_error_set(
5306
0
     error,
5307
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5308
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5309
0
     "%s: invalid handle - missing file io pool.",
5310
0
     function );
5311
5312
0
    return( -1 );
5313
0
  }
5314
/* TODO add thread-safety support */
5315
0
  if( libfvalue_table_get_number_of_values(
5316
0
       internal_handle->integrity_hash_values,
5317
0
       number_of_integrity_hash_values,
5318
0
       error ) != 1 )
5319
0
  {
5320
0
    libcerror_error_set(
5321
0
     error,
5322
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5323
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5324
0
     "%s: unable to retrieve number of integrity hash values.",
5325
0
     function );
5326
5327
0
    return( -1 );
5328
0
  }
5329
0
  return( 1 );
5330
0
}
5331
5332
/* Retrieves the size of a specific integrity hash value identifier
5333
 * The identifier size includes the end of string character
5334
 * Returns 1 if successful or -1 on error
5335
 */
5336
int libsmraw_handle_get_integrity_hash_value_identifier_size(
5337
     libsmraw_handle_t *handle,
5338
     int integrity_hash_value_index,
5339
     size_t *identifier_size,
5340
     libcerror_error_t **error )
5341
0
{
5342
0
  libsmraw_internal_handle_t *internal_handle = NULL;
5343
0
  libfvalue_value_t *value                    = NULL;
5344
0
  uint8_t *value_identifier                   = NULL;
5345
0
  static char *function                       = "libsmraw_handle_get_integrity_hash_value_identifier_size";
5346
5347
0
  if( handle == NULL )
5348
0
  {
5349
0
    libcerror_error_set(
5350
0
     error,
5351
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5352
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5353
0
     "%s: invalid handle.",
5354
0
     function );
5355
5356
0
    return( -1 );
5357
0
  }
5358
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
5359
5360
0
  if( internal_handle->file_io_pool == NULL )
5361
0
  {
5362
0
    libcerror_error_set(
5363
0
     error,
5364
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5365
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5366
0
     "%s: invalid handle - missing file io pool.",
5367
0
     function );
5368
5369
0
    return( -1 );
5370
0
  }
5371
/* TODO add thread-safety support */
5372
0
  if( libfvalue_table_get_value_by_index(
5373
0
       internal_handle->integrity_hash_values,
5374
0
       integrity_hash_value_index,
5375
0
       &value,
5376
0
       error ) != 1 )
5377
0
  {
5378
0
    libcerror_error_set(
5379
0
     error,
5380
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5381
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5382
0
     "%s: unable to retrieve value: %d from integrity hash values table.",
5383
0
     function,
5384
0
     integrity_hash_value_index );
5385
5386
0
    return( -1 );
5387
0
  }
5388
0
  if( libfvalue_value_get_identifier(
5389
0
       value,
5390
0
       &value_identifier,
5391
0
       identifier_size,
5392
0
       error ) != 1 )
5393
0
  {
5394
0
    libcerror_error_set(
5395
0
     error,
5396
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5397
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5398
0
     "%s: unable to retrieve value identifier: %d.",
5399
0
     function,
5400
0
     integrity_hash_value_index );
5401
5402
0
    return( -1 );
5403
0
  }
5404
0
  if( value_identifier == NULL )
5405
0
  {
5406
0
    libcerror_error_set(
5407
0
     error,
5408
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5409
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5410
0
     "%s: missing value identifier: %d.",
5411
0
     function,
5412
0
     integrity_hash_value_index );
5413
5414
0
    return( -1 );
5415
0
  }
5416
0
  return( 1 );
5417
0
}
5418
5419
/* Retrieves a specific integrity hash value identifier
5420
 * The identifier size should include the end of string character
5421
 * Returns 1 if successful or -1 on error
5422
 */
5423
int libsmraw_handle_get_integrity_hash_value_identifier(
5424
     libsmraw_handle_t *handle,
5425
     int integrity_hash_value_index,
5426
     uint8_t *identifier,
5427
     size_t identifier_size,
5428
     libcerror_error_t **error )
5429
0
{
5430
0
  libsmraw_internal_handle_t *internal_handle = NULL;
5431
0
  libfvalue_value_t *value                    = NULL;
5432
0
  uint8_t *value_identifier                   = NULL;
5433
0
  static char *function                       = "libsmraw_handle_get_integrity_hash_value_identifier";
5434
0
  size_t value_identifier_size                = 0;
5435
5436
0
  if( handle == NULL )
5437
0
  {
5438
0
    libcerror_error_set(
5439
0
     error,
5440
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5441
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5442
0
     "%s: invalid handle.",
5443
0
     function );
5444
5445
0
    return( -1 );
5446
0
  }
5447
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
5448
5449
0
  if( internal_handle->file_io_pool == NULL )
5450
0
  {
5451
0
    libcerror_error_set(
5452
0
     error,
5453
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5454
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5455
0
     "%s: invalid handle - missing file io pool.",
5456
0
     function );
5457
5458
0
    return( -1 );
5459
0
  }
5460
/* TODO add thread-safety support */
5461
0
  if( libfvalue_table_get_value_by_index(
5462
0
       internal_handle->integrity_hash_values,
5463
0
       integrity_hash_value_index,
5464
0
       &value,
5465
0
       error ) != 1 )
5466
0
  {
5467
0
    libcerror_error_set(
5468
0
     error,
5469
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5470
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5471
0
     "%s: unable to retrieve value: %d from integrity hash values table.",
5472
0
     function,
5473
0
     integrity_hash_value_index );
5474
5475
0
    return( -1 );
5476
0
  }
5477
0
  if( libfvalue_value_get_identifier(
5478
0
       value,
5479
0
       &value_identifier,
5480
0
       &value_identifier_size,
5481
0
       error ) != 1 )
5482
0
  {
5483
0
    libcerror_error_set(
5484
0
     error,
5485
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5486
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5487
0
     "%s: unable to retrieve value identifier: %d.",
5488
0
     function,
5489
0
     integrity_hash_value_index );
5490
5491
0
    return( -1 );
5492
0
  }
5493
0
  if( value_identifier == NULL )
5494
0
  {
5495
0
    libcerror_error_set(
5496
0
     error,
5497
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5498
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5499
0
     "%s: missing value identifier: %d.",
5500
0
     function,
5501
0
     integrity_hash_value_index );
5502
5503
0
    return( -1 );
5504
0
  }
5505
0
  if( identifier_size < value_identifier_size )
5506
0
  {
5507
0
    libcerror_error_set(
5508
0
     error,
5509
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5510
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
5511
0
     "%s: identifier too small.",
5512
0
     function );
5513
5514
0
    return( -1 );
5515
0
  }
5516
0
  if( memory_copy(
5517
0
       identifier,
5518
0
       value_identifier,
5519
0
       value_identifier_size ) == NULL )
5520
0
  {
5521
0
    libcerror_error_set(
5522
0
     error,
5523
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
5524
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
5525
0
     "%s: unable to copy identifier.",
5526
0
     function );
5527
5528
0
    return( -1 );
5529
0
  }
5530
0
  return( 1 );
5531
0
}
5532
5533
/* Retrieves the size of an UTF-8 encoded integrity hash value for the specific identifier
5534
 * The value size includes the end of string character
5535
 * Returns 1 if successful, 0 if value not present or -1 on error
5536
 */
5537
int libsmraw_handle_get_utf8_integrity_hash_value_size(
5538
     libsmraw_handle_t *handle,
5539
     const uint8_t *identifier,
5540
     size_t identifier_length,
5541
     size_t *utf8_string_size,
5542
     libcerror_error_t **error )
5543
0
{
5544
0
  libsmraw_internal_handle_t *internal_handle = NULL;
5545
0
  libfvalue_value_t *value                    = NULL;
5546
0
  static char *function                       = "libsmraw_handle_get_utf8_integrity_hash_value_size";
5547
0
  int result                                  = 0;
5548
5549
0
  if( handle == NULL )
5550
0
  {
5551
0
    libcerror_error_set(
5552
0
     error,
5553
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5554
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5555
0
     "%s: invalid handle.",
5556
0
     function );
5557
5558
0
    return( -1 );
5559
0
  }
5560
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
5561
5562
0
  if( internal_handle->file_io_pool == NULL )
5563
0
  {
5564
0
    libcerror_error_set(
5565
0
     error,
5566
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5567
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5568
0
     "%s: invalid handle - missing file io pool.",
5569
0
     function );
5570
5571
0
    return( -1 );
5572
0
  }
5573
0
  if( identifier == NULL )
5574
0
  {
5575
0
    libcerror_error_set(
5576
0
     error,
5577
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5578
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5579
0
     "%s: invalid identifier.",
5580
0
     function );
5581
5582
0
    return( -1 );
5583
0
  }
5584
/* TODO add thread-safety support */
5585
0
  result = libfvalue_table_get_value_by_identifier(
5586
0
            internal_handle->integrity_hash_values,
5587
0
            identifier,
5588
0
            identifier_length + 1,
5589
0
            &value,
5590
0
            0,
5591
0
            error );
5592
5593
0
  if( result == -1 )
5594
0
  {
5595
0
    libcerror_error_set(
5596
0
     error,
5597
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5598
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5599
0
     "%s: unable to retrieve value: %s from integrity hash values table.",
5600
0
     function,
5601
0
     (char *) identifier );
5602
5603
0
    return( -1 );
5604
0
  }
5605
0
  else if( result != 0 )
5606
0
  {
5607
0
    if( libfvalue_value_get_utf8_string_size(
5608
0
         value,
5609
0
         0,
5610
0
         utf8_string_size,
5611
0
         error ) != 1 )
5612
0
    {
5613
0
      libcerror_error_set(
5614
0
       error,
5615
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5616
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5617
0
       "%s: unable to retrieve value: %s UTF-8 string size.",
5618
0
       function,
5619
0
       (char *) identifier );
5620
5621
0
      return( -1 );
5622
0
    }
5623
0
  }
5624
0
  return( result );
5625
0
}
5626
5627
/* Retrieves an UTF-8 encoded integrity hash value for the specific identifier
5628
 * The value size should include the end of string character
5629
 * Returns 1 if successful, 0 if value not present or -1 on error
5630
 */
5631
int libsmraw_handle_get_utf8_integrity_hash_value(
5632
     libsmraw_handle_t *handle,
5633
     const uint8_t *identifier,
5634
     size_t identifier_length,
5635
     uint8_t *utf8_string,
5636
     size_t utf8_string_size,
5637
     libcerror_error_t **error )
5638
0
{
5639
0
  libsmraw_internal_handle_t *internal_handle = NULL;
5640
0
  libfvalue_value_t *value                    = NULL;
5641
0
  static char *function                       = "libsmraw_handle_get_utf8_integrity_hash_value";
5642
0
  int result                                  = 0;
5643
5644
0
  if( handle == NULL )
5645
0
  {
5646
0
    libcerror_error_set(
5647
0
     error,
5648
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5649
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5650
0
     "%s: invalid handle.",
5651
0
     function );
5652
5653
0
    return( -1 );
5654
0
  }
5655
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
5656
5657
0
  if( internal_handle->file_io_pool == NULL )
5658
0
  {
5659
0
    libcerror_error_set(
5660
0
     error,
5661
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5662
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5663
0
     "%s: invalid handle - missing file io pool.",
5664
0
     function );
5665
5666
0
    return( -1 );
5667
0
  }
5668
0
  if( identifier == NULL )
5669
0
  {
5670
0
    libcerror_error_set(
5671
0
     error,
5672
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5673
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5674
0
     "%s: invalid identifier.",
5675
0
     function );
5676
5677
0
    return( -1 );
5678
0
  }
5679
/* TODO add thread-safety support */
5680
0
  result = libfvalue_table_get_value_by_identifier(
5681
0
            internal_handle->integrity_hash_values,
5682
0
            identifier,
5683
0
            identifier_length + 1,
5684
0
            &value,
5685
0
            0,
5686
0
            error );
5687
5688
0
  if( result == -1 )
5689
0
  {
5690
0
    libcerror_error_set(
5691
0
     error,
5692
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5693
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5694
0
     "%s: unable to retrieve value: %s from integrity hash values table.",
5695
0
     function,
5696
0
     (char *) identifier );
5697
5698
0
    return( -1 );
5699
0
  }
5700
0
  else if( result != 0 )
5701
0
  {
5702
0
    if( libfvalue_value_copy_to_utf8_string(
5703
0
         value,
5704
0
         0,
5705
0
         utf8_string,
5706
0
         utf8_string_size,
5707
0
         error ) != 1 )
5708
0
    {
5709
0
      libcerror_error_set(
5710
0
       error,
5711
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5712
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
5713
0
       "%s: unable to copy value: %s to an UTF-8 string.",
5714
0
       function,
5715
0
       (char *) identifier );
5716
5717
0
      return( -1 );
5718
0
    }
5719
0
  }
5720
0
  return( result );
5721
0
}
5722
5723
/* Sets an UTF-8 encoded integrity hash value for the specific identifier
5724
 * Returns the 1 if succesful or -1 on error
5725
 */
5726
int libsmraw_handle_set_utf8_integrity_hash_value(
5727
     libsmraw_handle_t *handle,
5728
     const uint8_t *identifier,
5729
     size_t identifier_length,
5730
     const uint8_t *utf8_string,
5731
     size_t utf8_string_length,
5732
     libcerror_error_t **error )
5733
0
{
5734
0
  libsmraw_internal_handle_t *internal_handle = NULL;
5735
0
  libfvalue_value_t *value                    = NULL;
5736
0
  static char *function                       = "libsmraw_handle_set_utf8_integrity_hash_value";
5737
0
  int result                                  = 0;
5738
5739
0
  if( handle == NULL )
5740
0
  {
5741
0
    libcerror_error_set(
5742
0
     error,
5743
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5744
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5745
0
     "%s: invalid handle.",
5746
0
     function );
5747
5748
0
    return( -1 );
5749
0
  }
5750
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
5751
5752
0
  if( internal_handle->read_values_initialized != 0 )
5753
0
  {
5754
0
    libcerror_error_set(
5755
0
     error,
5756
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5757
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5758
0
     "%s: integrity hash values cannot be changed.",
5759
0
     function );
5760
5761
0
    return( -1 );
5762
0
  }
5763
0
  if( identifier == NULL )
5764
0
  {
5765
0
    libcerror_error_set(
5766
0
     error,
5767
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5768
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5769
0
     "%s: invalid identifier.",
5770
0
     function );
5771
5772
0
    return( -1 );
5773
0
  }
5774
/* TODO add thread-safety support */
5775
0
  result = libfvalue_table_get_value_by_identifier(
5776
0
            internal_handle->integrity_hash_values,
5777
0
            identifier,
5778
0
            identifier_length + 1,
5779
0
            &value,
5780
0
            0,
5781
0
            error );
5782
5783
0
  if( result == -1 )
5784
0
  {
5785
0
    libcerror_error_set(
5786
0
     error,
5787
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5788
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5789
0
     "%s: unable to retrieve value: %s from integrity hash values table.",
5790
0
     function,
5791
0
     (char *) identifier );
5792
5793
0
    return( -1 );
5794
0
  }
5795
0
  else if( result == 0 )
5796
0
  {
5797
0
    if( libfvalue_value_type_initialize(
5798
0
         &value,
5799
0
         LIBFVALUE_VALUE_TYPE_STRING_UTF8,
5800
0
         error ) != 1 )
5801
0
    {
5802
0
      libcerror_error_set(
5803
0
       error,
5804
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5805
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5806
0
       "%s: unable to create value.",
5807
0
       function );
5808
5809
0
      return( -1 );
5810
0
    }
5811
0
    if( libfvalue_value_set_identifier(
5812
0
         value,
5813
0
         identifier,
5814
0
         identifier_length + 1,
5815
0
         LIBFVALUE_VALUE_IDENTIFIER_FLAG_MANAGED,
5816
0
         error ) != 1 )
5817
0
    {
5818
0
      libcerror_error_set(
5819
0
       error,
5820
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5821
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5822
0
       "%s: unable to set identifier in value.",
5823
0
       function );
5824
5825
0
      libfvalue_value_free(
5826
0
       &value,
5827
0
       NULL );
5828
5829
0
      return( -1 );
5830
0
    }
5831
0
    if( libfvalue_table_set_value(
5832
0
         internal_handle->integrity_hash_values,
5833
0
         value,
5834
0
         error ) != 1 )
5835
0
    {
5836
0
      libcerror_error_set(
5837
0
       error,
5838
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5839
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5840
0
       "%s: unable to set value: %s in integrity hash values table.",
5841
0
       function,
5842
0
       (char *) identifier );
5843
5844
0
      libfvalue_value_free(
5845
0
       &value,
5846
0
       NULL );
5847
5848
0
      return( -1 );
5849
0
    }
5850
0
  }
5851
0
  if( libfvalue_value_copy_from_utf8_string(
5852
0
       value,
5853
0
       0,
5854
0
       utf8_string,
5855
0
       utf8_string_length + 1,
5856
0
       error ) != 1 )
5857
0
  {
5858
0
    libcerror_error_set(
5859
0
     error,
5860
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5861
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
5862
0
     "%s: unable to copy value: %s from an UTF-8 string.",
5863
0
     function,
5864
0
     (char *) identifier );
5865
5866
0
    return( -1 );
5867
0
  }
5868
0
  return( 1 );
5869
0
}
5870
5871
/* Retrieves the size of an UTF-16 encoded integrity hash value for the specific identifier
5872
 * The value size includes the end of string character
5873
 * Returns 1 if successful, 0 if value not present or -1 on error
5874
 */
5875
int libsmraw_handle_get_utf16_integrity_hash_value_size(
5876
     libsmraw_handle_t *handle,
5877
     const uint8_t *identifier,
5878
     size_t identifier_length,
5879
     size_t *utf16_string_size,
5880
     libcerror_error_t **error )
5881
0
{
5882
0
  libsmraw_internal_handle_t *internal_handle = NULL;
5883
0
  libfvalue_value_t *value                    = NULL;
5884
0
  static char *function                       = "libsmraw_handle_get_utf16_integrity_hash_value_size";
5885
0
  int result                                  = 0;
5886
5887
0
  if( handle == NULL )
5888
0
  {
5889
0
    libcerror_error_set(
5890
0
     error,
5891
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5892
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5893
0
     "%s: invalid handle.",
5894
0
     function );
5895
5896
0
    return( -1 );
5897
0
  }
5898
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
5899
5900
0
  if( internal_handle->file_io_pool == NULL )
5901
0
  {
5902
0
    libcerror_error_set(
5903
0
     error,
5904
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5905
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5906
0
     "%s: invalid handle - missing file io pool.",
5907
0
     function );
5908
5909
0
    return( -1 );
5910
0
  }
5911
0
  if( identifier == NULL )
5912
0
  {
5913
0
    libcerror_error_set(
5914
0
     error,
5915
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5916
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5917
0
     "%s: invalid identifier.",
5918
0
     function );
5919
5920
0
    return( -1 );
5921
0
  }
5922
/* TODO add thread-safety support */
5923
0
  result = libfvalue_table_get_value_by_identifier(
5924
0
            internal_handle->integrity_hash_values,
5925
0
            identifier,
5926
0
            identifier_length + 1,
5927
0
            &value,
5928
0
            0,
5929
0
            error );
5930
5931
0
  if( result == -1 )
5932
0
  {
5933
0
    libcerror_error_set(
5934
0
     error,
5935
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5936
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5937
0
     "%s: unable to retrieve value: %s from integrity hash values table.",
5938
0
     function,
5939
0
     (char *) identifier );
5940
5941
0
    return( -1 );
5942
0
  }
5943
0
  else if( result != 0 )
5944
0
  {
5945
0
    if( libfvalue_value_get_utf16_string_size(
5946
0
         value,
5947
0
         0,
5948
0
         utf16_string_size,
5949
0
         error ) != 1 )
5950
0
    {
5951
0
      libcerror_error_set(
5952
0
       error,
5953
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5954
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5955
0
       "%s: unable to retrieve value: %s UTF-16 string size.",
5956
0
       function,
5957
0
       (char *) identifier );
5958
5959
0
      return( -1 );
5960
0
    }
5961
0
  }
5962
0
  return( result );
5963
0
}
5964
5965
/* Retrieves an UTF-16 encoded integrity hash value for the specific identifier
5966
 * The value size should include the end of string character
5967
 * Returns 1 if successful, 0 if value not present or -1 on error
5968
 */
5969
int libsmraw_handle_get_utf16_integrity_hash_value(
5970
     libsmraw_handle_t *handle,
5971
     const uint8_t *identifier,
5972
     size_t identifier_length,
5973
     uint16_t *utf16_string,
5974
     size_t utf16_string_size,
5975
     libcerror_error_t **error )
5976
0
{
5977
0
  libsmraw_internal_handle_t *internal_handle = NULL;
5978
0
  libfvalue_value_t *value                    = NULL;
5979
0
  static char *function                       = "libsmraw_handle_get_utf16_integrity_hash_value";
5980
0
  int result                                  = 0;
5981
5982
0
  if( handle == NULL )
5983
0
  {
5984
0
    libcerror_error_set(
5985
0
     error,
5986
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5987
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5988
0
     "%s: invalid handle.",
5989
0
     function );
5990
5991
0
    return( -1 );
5992
0
  }
5993
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
5994
5995
0
  if( internal_handle->file_io_pool == NULL )
5996
0
  {
5997
0
    libcerror_error_set(
5998
0
     error,
5999
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6000
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6001
0
     "%s: invalid handle - missing file io pool.",
6002
0
     function );
6003
6004
0
    return( -1 );
6005
0
  }
6006
0
  if( identifier == NULL )
6007
0
  {
6008
0
    libcerror_error_set(
6009
0
     error,
6010
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6011
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6012
0
     "%s: invalid identifier.",
6013
0
     function );
6014
6015
0
    return( -1 );
6016
0
  }
6017
/* TODO add thread-safety support */
6018
0
  result = libfvalue_table_get_value_by_identifier(
6019
0
            internal_handle->integrity_hash_values,
6020
0
            identifier,
6021
0
            identifier_length + 1,
6022
0
            &value,
6023
0
            0,
6024
0
            error );
6025
6026
0
  if( result == -1 )
6027
0
  {
6028
0
    libcerror_error_set(
6029
0
     error,
6030
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6031
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6032
0
     "%s: unable to retrieve value: %s from integrity hash values table.",
6033
0
     function,
6034
0
     (char *) identifier );
6035
6036
0
    return( -1 );
6037
0
  }
6038
0
  else if( result != 0 )
6039
0
  {
6040
0
    if( libfvalue_value_copy_to_utf16_string(
6041
0
         value,
6042
0
         0,
6043
0
         utf16_string,
6044
0
         utf16_string_size,
6045
0
         error ) != 1 )
6046
0
    {
6047
0
      libcerror_error_set(
6048
0
       error,
6049
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6050
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
6051
0
       "%s: unable to copy value: %s to an UTF-16 string.",
6052
0
       function,
6053
0
       (char *) identifier );
6054
6055
0
      return( -1 );
6056
0
    }
6057
0
  }
6058
0
  return( result );
6059
0
}
6060
6061
/* Sets an UTF-16 encoded integrity hash value for the specific identifier
6062
 * Returns the 1 if succesful or -1 on error
6063
 */
6064
int libsmraw_handle_set_utf16_integrity_hash_value(
6065
     libsmraw_handle_t *handle,
6066
     const uint8_t *identifier,
6067
     size_t identifier_length,
6068
     const uint16_t *utf16_string,
6069
     size_t utf16_string_length,
6070
     libcerror_error_t **error )
6071
0
{
6072
0
  libsmraw_internal_handle_t *internal_handle = NULL;
6073
0
  libfvalue_value_t *value                    = NULL;
6074
0
  static char *function                       = "libsmraw_handle_set_utf16_integrity_hash_value";
6075
0
  int result                                  = 0;
6076
6077
0
  if( handle == NULL )
6078
0
  {
6079
0
    libcerror_error_set(
6080
0
     error,
6081
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6082
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6083
0
     "%s: invalid handle.",
6084
0
     function );
6085
6086
0
    return( -1 );
6087
0
  }
6088
0
  internal_handle = (libsmraw_internal_handle_t *) handle;
6089
6090
0
  if( internal_handle->read_values_initialized != 0 )
6091
0
  {
6092
0
    libcerror_error_set(
6093
0
     error,
6094
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6095
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6096
0
     "%s: integrity hash values cannot be changed.",
6097
0
     function );
6098
6099
0
    return( -1 );
6100
0
  }
6101
0
  if( identifier == NULL )
6102
0
  {
6103
0
    libcerror_error_set(
6104
0
     error,
6105
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6106
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6107
0
     "%s: invalid identifier.",
6108
0
     function );
6109
6110
0
    return( -1 );
6111
0
  }
6112
/* TODO add thread-safety support */
6113
0
  result = libfvalue_table_get_value_by_identifier(
6114
0
            internal_handle->integrity_hash_values,
6115
0
            identifier,
6116
0
            identifier_length + 1,
6117
0
            &value,
6118
0
            0,
6119
0
            error );
6120
6121
0
  if( result == -1 )
6122
0
  {
6123
0
    libcerror_error_set(
6124
0
     error,
6125
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6126
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6127
0
     "%s: unable to retrieve value: %s from integrity hash values table.",
6128
0
     function,
6129
0
     (char *) identifier );
6130
6131
0
    return( -1 );
6132
0
  }
6133
0
  else if( result == 0 )
6134
0
  {
6135
0
    if( libfvalue_value_type_initialize(
6136
0
         &value,
6137
0
         LIBFVALUE_VALUE_TYPE_STRING_UTF8,
6138
0
         error ) != 1 )
6139
0
    {
6140
0
      libcerror_error_set(
6141
0
       error,
6142
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6143
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6144
0
       "%s: unable to create value.",
6145
0
       function );
6146
6147
0
      return( -1 );
6148
0
    }
6149
0
    if( libfvalue_value_set_identifier(
6150
0
         value,
6151
0
         identifier,
6152
0
         identifier_length + 1,
6153
0
         LIBFVALUE_VALUE_IDENTIFIER_FLAG_MANAGED,
6154
0
         error ) != 1 )
6155
0
    {
6156
0
      libcerror_error_set(
6157
0
       error,
6158
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6159
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6160
0
       "%s: unable to set identifier in value.",
6161
0
       function );
6162
6163
0
      libfvalue_value_free(
6164
0
       &value,
6165
0
       NULL );
6166
6167
0
      return( -1 );
6168
0
    }
6169
0
    if( libfvalue_table_set_value(
6170
0
         internal_handle->integrity_hash_values,
6171
0
         value,
6172
0
         error ) != 1 )
6173
0
    {
6174
0
      libcerror_error_set(
6175
0
       error,
6176
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6177
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6178
0
       "%s: unable to set value: %s in integrity hash values table.",
6179
0
       function,
6180
0
       (char *) identifier );
6181
6182
0
      libfvalue_value_free(
6183
0
       &value,
6184
0
       NULL );
6185
6186
0
      return( -1 );
6187
0
    }
6188
0
  }
6189
0
  if( libfvalue_value_copy_from_utf16_string(
6190
0
       value,
6191
0
       0,
6192
0
       utf16_string,
6193
0
       utf16_string_length + 1,
6194
0
       error ) != 1 )
6195
0
  {
6196
0
    libcerror_error_set(
6197
0
     error,
6198
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6199
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
6200
0
     "%s: unable to copy value: %s from an UTF-16 string.",
6201
0
     function,
6202
0
     (char *) identifier );
6203
6204
0
    return( -1 );
6205
0
  }
6206
0
  return( 1 );
6207
0
}
6208