Coverage Report

Created: 2024-02-25 07:20

/src/libvmdk/libvmdk/libvmdk_extent_table.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Extent table functions
3
 *
4
 * Copyright (C) 2009-2023, 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 "libvmdk_definitions.h"
30
#include "libvmdk_extent_file.h"
31
#include "libvmdk_extent_table.h"
32
#include "libvmdk_extent_values.h"
33
#include "libvmdk_libbfio.h"
34
#include "libvmdk_libcdata.h"
35
#include "libvmdk_libcerror.h"
36
#include "libvmdk_libclocale.h"
37
#include "libvmdk_libcpath.h"
38
#include "libvmdk_libfcache.h"
39
#include "libvmdk_libfdata.h"
40
#include "libvmdk_libuna.h"
41
#include "libvmdk_system_string.h"
42
43
/* Creates an extent table
44
 * Make sure the value extent_table is referencing, is set to NULL
45
 * Returns 1 if successful or -1 on error
46
 */
47
int libvmdk_extent_table_initialize(
48
     libvmdk_extent_table_t **extent_table,
49
     libvmdk_io_handle_t *io_handle,
50
     libcerror_error_t **error )
51
8.00k
{
52
8.00k
  static char *function = "libvmdk_extent_table_initialize";
53
54
8.00k
  if( extent_table == NULL )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
59
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
60
0
     "%s: invalid extent table.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
8.00k
  if( *extent_table != NULL )
66
0
  {
67
0
    libcerror_error_set(
68
0
     error,
69
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
70
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
71
0
     "%s: invalid extent table value already set.",
72
0
     function );
73
74
0
    return( -1 );
75
0
  }
76
8.00k
  if( io_handle == NULL )
77
0
  {
78
0
    libcerror_error_set(
79
0
     error,
80
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
81
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
82
0
     "%s: invalid IO handle.",
83
0
     function );
84
85
0
    return( -1 );
86
0
  }
87
8.00k
  *extent_table = memory_allocate_structure(
88
8.00k
                   libvmdk_extent_table_t );
89
90
8.00k
  if( *extent_table == NULL )
91
0
  {
92
0
    libcerror_error_set(
93
0
     error,
94
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
95
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
96
0
     "%s: unable to create extent table.",
97
0
     function );
98
99
0
    goto on_error;
100
0
  }
101
8.00k
  if( memory_set(
102
8.00k
       *extent_table,
103
8.00k
       0,
104
8.00k
       sizeof( libvmdk_extent_table_t ) ) == NULL )
105
0
  {
106
0
    libcerror_error_set(
107
0
     error,
108
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
109
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
110
0
     "%s: unable to clear extent table.",
111
0
     function );
112
113
0
    goto on_error;
114
0
  }
115
8.00k
  ( *extent_table )->io_handle = io_handle;
116
117
8.00k
  return( 1 );
118
119
0
on_error:
120
0
  if( *extent_table != NULL )
121
0
  {
122
0
    memory_free(
123
0
     *extent_table );
124
125
0
    *extent_table = NULL;
126
0
  }
127
0
  return( -1 );
128
8.00k
}
129
130
/* Frees an extent table
131
 * Returns 1 if successful or -1 on error
132
 */
133
int libvmdk_extent_table_free(
134
     libvmdk_extent_table_t **extent_table,
135
     libcerror_error_t **error )
136
8.00k
{
137
8.00k
  static char *function = "libvmdk_extent_table_free";
138
8.00k
  int result            = 1;
139
140
8.00k
  if( extent_table == NULL )
141
0
  {
142
0
    libcerror_error_set(
143
0
     error,
144
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
145
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
146
0
     "%s: invalid extent table.",
147
0
     function );
148
149
0
    return( -1 );
150
0
  }
151
8.00k
  if( *extent_table != NULL )
152
8.00k
  {
153
8.00k
    if( libvmdk_extent_table_clear(
154
8.00k
         *extent_table,
155
8.00k
         error ) != 1 )
156
0
    {
157
0
      libcerror_error_set(
158
0
       error,
159
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
160
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
161
0
       "%s: unable to clear extent table.",
162
0
       function );
163
164
0
      result = -1;
165
0
    }
166
8.00k
    memory_free(
167
8.00k
     *extent_table );
168
169
8.00k
    *extent_table = NULL;
170
8.00k
  }
171
8.00k
  return( result );
172
8.00k
}
173
174
/* Clears the extent table
175
 * Returns 1 if successful or -1 on error
176
 */
177
int libvmdk_extent_table_clear(
178
     libvmdk_extent_table_t *extent_table,
179
     libcerror_error_t **error )
180
8.57k
{
181
8.57k
  static char *function = "libvmdk_extent_table_clear";
182
8.57k
  int result            = 1;
183
184
8.57k
  if( extent_table == NULL )
185
0
  {
186
0
    libcerror_error_set(
187
0
     error,
188
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
189
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
190
0
     "%s: invalid extent table.",
191
0
     function );
192
193
0
    return( -1 );
194
0
  }
195
8.57k
  if( extent_table->data_files_path != NULL )
196
0
  {
197
0
    memory_free(
198
0
     extent_table->data_files_path );
199
200
0
    extent_table->data_files_path      = NULL;
201
0
    extent_table->data_files_path_size = 0;
202
0
  }
203
8.57k
  if( extent_table->extent_files_list != NULL )
204
0
  {
205
0
    if( libfdata_list_free(
206
0
         &( extent_table->extent_files_list ),
207
0
         error ) != 1 )
208
0
    {
209
0
      libcerror_error_set(
210
0
       error,
211
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
212
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
213
0
       "%s: unable to free extent files list.",
214
0
       function );
215
216
0
      result = -1;
217
0
    }
218
0
  }
219
8.57k
  if( extent_table->extent_files_cache != NULL )
220
0
  {
221
0
    if( libfcache_cache_free(
222
0
         &( extent_table->extent_files_cache ),
223
0
         error ) != 1 )
224
0
    {
225
0
      libcerror_error_set(
226
0
       error,
227
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
228
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
229
0
       "%s: unable to free extent files cache.",
230
0
       function );
231
232
0
      result = -1;
233
0
    }
234
0
  }
235
8.57k
  if( extent_table->extent_files_stream != NULL )
236
0
  {
237
0
    if( libfdata_stream_free(
238
0
         &( extent_table->extent_files_stream ),
239
0
         error ) != 1 )
240
0
    {
241
0
      libcerror_error_set(
242
0
       error,
243
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
244
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
245
0
       "%s: unable to free extent files stream.",
246
0
       function );
247
248
0
      result = -1;
249
0
    }
250
0
  }
251
8.57k
  if( memory_set(
252
8.57k
       extent_table,
253
8.57k
       0,
254
8.57k
       sizeof( libvmdk_extent_table_t ) ) == NULL )
255
0
  {
256
0
    libcerror_error_set(
257
0
     error,
258
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
259
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
260
0
     "%s: unable to extent table.",
261
0
     function );
262
263
0
    result = -1;
264
0
  }
265
8.57k
  return( result );
266
8.57k
}
267
268
/* Retrieves the size of the data file_path
269
 * Returns 1 if successful, 0 if value not present or -1 on error
270
 */
271
int libvmdk_extent_table_get_data_files_path_size(
272
     libvmdk_extent_table_t *extent_table,
273
     size_t *path_size,
274
     libcerror_error_t **error )
275
0
{
276
0
  static char *function = "libvmdk_extent_table_get_data_files_path_size";
277
278
0
  if( extent_table == NULL )
279
0
  {
280
0
    libcerror_error_set(
281
0
     error,
282
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
283
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
284
0
     "%s: invalid extent table.",
285
0
     function );
286
287
0
    return( -1 );
288
0
  }
289
0
  if( extent_table->data_files_path == NULL )
290
0
  {
291
0
    return( 0 );
292
0
  }
293
0
  if( libvmdk_system_string_size_to_narrow_string(
294
0
       extent_table->data_files_path,
295
0
       extent_table->data_files_path_size,
296
0
       path_size,
297
0
       error ) != 1 )
298
0
  {
299
0
    libcerror_error_set(
300
0
     error,
301
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
302
0
     LIBCERROR_CONVERSION_ERROR_GENERIC,
303
0
     "%s: unable to determine data files path size.",
304
0
     function );
305
306
0
    return( -1 );
307
0
  }
308
0
  return( 1 );
309
0
}
310
311
/* Retrieves the data files path
312
 * Returns 1 if successful, 0 if value not present or -1 on error
313
 */
314
int libvmdk_extent_table_get_data_files_path(
315
     libvmdk_extent_table_t *extent_table,
316
     char *path,
317
     size_t path_size,
318
     libcerror_error_t **error )
319
0
{
320
0
  static char *function   = "libvmdk_extent_table_get_data_files_path";
321
0
  size_t narrow_path_size = 0;
322
323
0
  if( extent_table == NULL )
324
0
  {
325
0
    libcerror_error_set(
326
0
     error,
327
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
328
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
329
0
     "%s: invalid extent table.",
330
0
     function );
331
332
0
    return( -1 );
333
0
  }
334
0
  if( path == NULL )
335
0
  {
336
0
    libcerror_error_set(
337
0
     error,
338
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
339
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
340
0
     "%s: invalid path.",
341
0
     function );
342
343
0
    return( -1 );
344
0
  }
345
0
  if( path_size > (size_t) SSIZE_MAX )
346
0
  {
347
0
    libcerror_error_set(
348
0
     error,
349
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
350
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
351
0
     "%s: invalid path size value exceeds maximum.",
352
0
     function );
353
354
0
    return( -1 );
355
0
  }
356
0
  if( extent_table->data_files_path == NULL )
357
0
  {
358
0
    return( 0 );
359
0
  }
360
0
  if( libvmdk_system_string_size_to_narrow_string(
361
0
       extent_table->data_files_path,
362
0
       extent_table->data_files_path_size,
363
0
       &narrow_path_size,
364
0
       error ) != 1 )
365
0
  {
366
0
    libcerror_error_set(
367
0
     error,
368
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
369
0
     LIBCERROR_CONVERSION_ERROR_GENERIC,
370
0
     "%s: unable to determine data files path size.",
371
0
     function );
372
373
0
    return( -1 );
374
0
  }
375
0
  if( path_size < narrow_path_size )
376
0
  {
377
0
    libcerror_error_set(
378
0
     error,
379
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
380
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
381
0
     "%s: path too small.",
382
0
     function );
383
384
0
    return( -1 );
385
0
  }
386
0
  if( libvmdk_system_string_copy_to_narrow_string(
387
0
       extent_table->data_files_path,
388
0
       extent_table->data_files_path_size,
389
0
       path,
390
0
       path_size,
391
0
       error ) != 1 )
392
0
  {
393
0
    libcerror_error_set(
394
0
     error,
395
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
396
0
     LIBCERROR_CONVERSION_ERROR_GENERIC,
397
0
     "%s: unable to set data files path.",
398
0
     function );
399
400
0
    return( -1 );
401
0
  }
402
0
  return( 1 );
403
0
}
404
405
/* Sets the data files path
406
 * Returns 1 if successful or -1 on error
407
 */
408
int libvmdk_extent_table_set_data_files_path(
409
     libvmdk_extent_table_t *extent_table,
410
     const char *path,
411
     size_t path_length,
412
     libcerror_error_t **error )
413
0
{
414
0
  static char *function = "libvmdk_extent_table_set_data_files_path";
415
416
0
  if( extent_table == NULL )
417
0
  {
418
0
    libcerror_error_set(
419
0
     error,
420
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
421
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
422
0
     "%s: invalid extent table.",
423
0
     function );
424
425
0
    return( -1 );
426
0
  }
427
0
  if( path == NULL )
428
0
  {
429
0
    libcerror_error_set(
430
0
     error,
431
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
432
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
433
0
     "%s: invalid path.",
434
0
     function );
435
436
0
    return( -1 );
437
0
  }
438
0
  if( path_length > (size_t) ( SSIZE_MAX - 1 ) )
439
0
  {
440
0
    libcerror_error_set(
441
0
     error,
442
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
443
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
444
0
     "%s: invalid path length value exceeds maximum.",
445
0
     function );
446
447
0
    return( -1 );
448
0
  }
449
0
  if( extent_table->data_files_path != NULL )
450
0
  {
451
0
    memory_free(
452
0
     extent_table->data_files_path );
453
454
0
    extent_table->data_files_path      = NULL;
455
0
    extent_table->data_files_path_size = 0;
456
0
  }
457
0
  if( libvmdk_system_string_size_from_narrow_string(
458
0
       path,
459
0
       path_length + 1,
460
0
       &( extent_table->data_files_path_size ),
461
0
       error ) != 1 )
462
0
  {
463
0
    libcerror_error_set(
464
0
     error,
465
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
466
0
     LIBCERROR_CONVERSION_ERROR_GENERIC,
467
0
     "%s: unable to determine data files path size.",
468
0
     function );
469
470
0
    goto on_error;
471
0
  }
472
0
  extent_table->data_files_path = system_string_allocate(
473
0
                                   extent_table->data_files_path_size );
474
475
0
  if( extent_table->data_files_path == NULL )
476
0
  {
477
0
    libcerror_error_set(
478
0
     error,
479
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
480
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
481
0
     "%s: unable to create data files path.",
482
0
     function );
483
484
0
    goto on_error;
485
0
  }
486
0
  if( libvmdk_system_string_copy_from_narrow_string(
487
0
       extent_table->data_files_path,
488
0
       extent_table->data_files_path_size,
489
0
       path,
490
0
       path_length + 1,
491
0
       error ) != 1 )
492
0
  {
493
0
    libcerror_error_set(
494
0
     error,
495
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
496
0
     LIBCERROR_CONVERSION_ERROR_GENERIC,
497
0
     "%s: unable to set data files path.",
498
0
     function );
499
500
0
    goto on_error;
501
0
  }
502
0
  return( 1 );
503
504
0
on_error:
505
0
  if( extent_table->data_files_path != NULL )
506
0
  {
507
0
    memory_free(
508
0
     extent_table->data_files_path );
509
510
0
    extent_table->data_files_path = NULL;
511
0
  }
512
0
  extent_table->data_files_path_size = 0;
513
514
0
  return( -1 );
515
0
}
516
517
#if defined( HAVE_WIDE_CHARACTER_TYPE )
518
519
/* Retrieves the size of the data files path
520
 * Returns 1 if successful, 0 if value not present or -1 on error
521
 */
522
int libvmdk_extent_table_get_data_files_path_size_wide(
523
     libvmdk_extent_table_t *extent_table,
524
     size_t *path_size,
525
     libcerror_error_t **error )
526
{
527
  static char *function = "libvmdk_extent_table_get_data_files_path_size_wide";
528
529
  if( extent_table == NULL )
530
  {
531
    libcerror_error_set(
532
     error,
533
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
534
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
535
     "%s: invalid extent table.",
536
     function );
537
538
    return( -1 );
539
  }
540
  if( path_size == NULL )
541
  {
542
    libcerror_error_set(
543
     error,
544
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
545
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
546
     "%s: invalid path size.",
547
     function );
548
549
    return( -1 );
550
  }
551
  if( extent_table->data_files_path == NULL )
552
  {
553
    return( 0 );
554
  }
555
  if( libvmdk_system_string_size_to_wide_string(
556
       extent_table->data_files_path,
557
       extent_table->data_files_path_size,
558
       path_size,
559
       error ) != 1 )
560
  {
561
    libcerror_error_set(
562
     error,
563
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
564
     LIBCERROR_CONVERSION_ERROR_GENERIC,
565
     "%s: unable to determine data files path size.",
566
     function );
567
568
    return( -1 );
569
  }
570
  return( 1 );
571
}
572
573
/* Retrieves the data files path
574
 * Returns 1 if successful, 0 if value not present or -1 on error
575
 */
576
int libvmdk_extent_table_get_data_files_path_wide(
577
     libvmdk_extent_table_t *extent_table,
578
     wchar_t *path,
579
     size_t path_size,
580
     libcerror_error_t **error )
581
{
582
  static char *function = "libvmdk_extent_table_get_data_files_path_wide";
583
  size_t wide_path_size = 0;
584
585
  if( extent_table == NULL )
586
  {
587
    libcerror_error_set(
588
     error,
589
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
590
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
591
     "%s: invalid extent table.",
592
     function );
593
594
    return( -1 );
595
  }
596
  if( path == NULL )
597
  {
598
    libcerror_error_set(
599
     error,
600
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
601
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
602
     "%s: invalid path.",
603
     function );
604
605
    return( -1 );
606
  }
607
  if( path_size > (size_t) SSIZE_MAX )
608
  {
609
    libcerror_error_set(
610
     error,
611
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
612
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
613
     "%s: invalid path size value exceeds maximum.",
614
     function );
615
616
    return( -1 );
617
  }
618
  if( extent_table->data_files_path == NULL )
619
  {
620
    return( 0 );
621
  }
622
  if( libvmdk_system_string_size_to_wide_string(
623
       extent_table->data_files_path,
624
       extent_table->data_files_path_size,
625
       &wide_path_size,
626
       error ) != 1 )
627
  {
628
    libcerror_error_set(
629
     error,
630
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
631
     LIBCERROR_CONVERSION_ERROR_GENERIC,
632
     "%s: unable to determine data files path size.",
633
     function );
634
635
    return( -1 );
636
  }
637
  if( path_size < wide_path_size )
638
  {
639
    libcerror_error_set(
640
     error,
641
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
642
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
643
     "%s: path too small.",
644
     function );
645
646
    return( -1 );
647
  }
648
  if( libvmdk_system_string_copy_to_wide_string(
649
       extent_table->data_files_path,
650
       extent_table->data_files_path_size,
651
       path,
652
       path_size,
653
       error ) != 1 )
654
  {
655
    libcerror_error_set(
656
     error,
657
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
658
     LIBCERROR_CONVERSION_ERROR_GENERIC,
659
     "%s: unable to set data files path.",
660
     function );
661
662
    return( -1 );
663
  }
664
  return( 1 );
665
}
666
667
/* Sets the data files path
668
 * Returns 1 if successful or -1 on error
669
 */
670
int libvmdk_extent_table_set_data_files_path_wide(
671
     libvmdk_extent_table_t *extent_table,
672
     const wchar_t *path,
673
     size_t path_length,
674
     libcerror_error_t **error )
675
{
676
  static char *function = "libvmdk_extent_table_set_data_files_path_wide";
677
678
  if( extent_table == NULL )
679
  {
680
    libcerror_error_set(
681
     error,
682
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
683
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
684
     "%s: invalid extent table.",
685
     function );
686
687
    return( -1 );
688
  }
689
  if( path == NULL )
690
  {
691
    libcerror_error_set(
692
     error,
693
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
694
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
695
     "%s: invalid  path.",
696
     function );
697
698
    return( -1 );
699
  }
700
  if( path_length > (size_t) ( SSIZE_MAX - 1 ) )
701
  {
702
    libcerror_error_set(
703
     error,
704
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
705
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
706
     "%s: invalid path length value exceeds maximum.",
707
     function );
708
709
    return( -1 );
710
  }
711
  if( extent_table->data_files_path != NULL )
712
  {
713
    memory_free(
714
     extent_table->data_files_path );
715
716
    extent_table->data_files_path      = NULL;
717
    extent_table->data_files_path_size = 0;
718
  }
719
  if( libvmdk_system_string_size_from_wide_string(
720
       path,
721
       path_length + 1,
722
       &( extent_table->data_files_path_size ),
723
       error ) != 1 )
724
  {
725
    libcerror_error_set(
726
     error,
727
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
728
     LIBCERROR_CONVERSION_ERROR_GENERIC,
729
     "%s: unable to determine data files path size.",
730
     function );
731
732
    goto on_error;
733
  }
734
  extent_table->data_files_path = system_string_allocate(
735
                                   extent_table->data_files_path_size );
736
737
  if( extent_table->data_files_path == NULL )
738
  {
739
    libcerror_error_set(
740
     error,
741
     LIBCERROR_ERROR_DOMAIN_MEMORY,
742
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
743
     "%s: unable to create data files path.",
744
     function );
745
746
    goto on_error;
747
  }
748
  if( libvmdk_system_string_copy_from_wide_string(
749
       extent_table->data_files_path,
750
       extent_table->data_files_path_size,
751
       path,
752
       path_length + 1,
753
       error ) != 1 )
754
  {
755
    libcerror_error_set(
756
     error,
757
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
758
     LIBCERROR_CONVERSION_ERROR_GENERIC,
759
     "%s: unable to set data files path.",
760
     function );
761
762
    goto on_error;
763
  }
764
  return( 1 );
765
766
on_error:
767
  if( extent_table->data_files_path != NULL )
768
  {
769
    memory_free(
770
     extent_table->data_files_path );
771
772
    extent_table->data_files_path = NULL;
773
  }
774
  extent_table->data_files_path_size = 0;
775
776
  return( -1 );
777
}
778
779
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
780
781
/* Retrieves the path of an extent data file 
782
 * Returns 1 if successful or -1 on error
783
 */
784
int libvmdk_extent_table_get_extent_data_file_path(
785
     libvmdk_extent_table_t *extent_table,
786
     libvmdk_extent_values_t *extent_values,
787
     char **path,
788
     size_t *path_size,
789
     libcerror_error_t **error )
790
0
{
791
0
  uint8_t *utf8_filename           = NULL;
792
0
  char *extent_data_filename       = NULL;
793
0
  static char *function            = "libvmdk_extent_table_get_extent_data_file_path";
794
0
  char *narrow_filename            = NULL;
795
0
  size_t extent_data_filename_size = 0;
796
0
  size_t narrow_filename_size      = 0;
797
0
  size_t utf8_filename_size        = 0;
798
799
0
  if( extent_table == NULL )
800
0
  {
801
0
    libcerror_error_set(
802
0
     error,
803
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
804
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
805
0
     "%s: invalid extent table.",
806
0
     function );
807
808
0
    return( -1 );
809
0
  }
810
0
  if( extent_values == NULL )
811
0
  {
812
0
    libcerror_error_set(
813
0
     error,
814
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
815
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
816
0
     "%s: invalid extent values.",
817
0
     function );
818
819
0
    return( -1 );
820
0
  }
821
0
  if( path == NULL )
822
0
  {
823
0
    libcerror_error_set(
824
0
     error,
825
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
826
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
827
0
     "%s: invalid path.",
828
0
     function );
829
830
0
    return( -1 );
831
0
  }
832
0
  if( path_size == NULL )
833
0
  {
834
0
    libcerror_error_set(
835
0
     error,
836
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
837
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
838
0
     "%s: invalid path size.",
839
0
     function );
840
841
0
    return( -1 );
842
0
  }
843
0
  if( libvmdk_extent_values_get_utf8_filename_size(
844
0
       extent_values,
845
0
       &utf8_filename_size,
846
0
       error ) != 1 )
847
0
  {
848
0
    libcerror_error_set(
849
0
     error,
850
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
851
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
852
0
     "%s: unable to retrieve UTF-8 extent filename size.",
853
0
     function );
854
855
0
    goto on_error;
856
0
  }
857
0
  if( ( utf8_filename_size == 0 )
858
0
   || ( utf8_filename_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
859
0
  {
860
0
    libcerror_error_set(
861
0
     error,
862
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
863
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
864
0
     "%s: invalid UTF-8 extent filename size value out of bounds.",
865
0
     function );
866
867
0
    goto on_error;
868
0
  }
869
0
  utf8_filename = (uint8_t *) memory_allocate(
870
0
                               sizeof( uint8_t ) * utf8_filename_size );
871
872
0
  if( utf8_filename == NULL )
873
0
  {
874
0
    libcerror_error_set(
875
0
     error,
876
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
877
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
878
0
     "%s: unable to create UTF-8 extent filename.",
879
0
     function );
880
881
0
    goto on_error;
882
0
  }
883
0
  if( libvmdk_extent_values_get_utf8_filename(
884
0
       extent_values,
885
0
       utf8_filename,
886
0
       utf8_filename_size,
887
0
       error ) != 1 )
888
0
  {
889
0
    libcerror_error_set(
890
0
     error,
891
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
892
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
893
0
     "%s: unable to retrieve UTF-8 extent filename.",
894
0
     function );
895
896
0
    goto on_error;
897
0
  }
898
0
  if( libclocale_codepage == 0 )
899
0
  {
900
0
    narrow_filename      = (char *) utf8_filename;
901
0
    narrow_filename_size = utf8_filename_size;
902
0
    utf8_filename        = NULL;
903
0
  }
904
0
  else
905
0
  {
906
0
    if( libuna_byte_stream_size_from_utf8(
907
0
         utf8_filename,
908
0
         utf8_filename_size,
909
0
         libclocale_codepage,
910
0
         &narrow_filename_size,
911
0
         error ) != 1)
912
0
    {
913
0
      libcerror_error_set(
914
0
       error,
915
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
916
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
917
0
       "%s: unable to retrieve narrow extent filename size.",
918
0
       function );
919
920
0
      goto on_error;
921
0
    }
922
0
    if( ( narrow_filename_size == 0 )
923
0
     || ( narrow_filename_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( char ) ) ) )
924
0
    {
925
0
      libcerror_error_set(
926
0
       error,
927
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
928
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
929
0
       "%s: invalid narrow extent filename size value out of bounds.",
930
0
       function );
931
932
0
      goto on_error;
933
0
    }
934
0
    narrow_filename = narrow_string_allocate(
935
0
                       narrow_filename_size );
936
937
0
    if( narrow_filename == NULL )
938
0
    {
939
0
      libcerror_error_set(
940
0
       error,
941
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
942
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
943
0
       "%s: unable to create narrow extent filename.",
944
0
       function );
945
946
0
      goto on_error;
947
0
    }
948
0
    if( libuna_byte_stream_copy_from_utf8(
949
0
         (uint8_t *) narrow_filename,
950
0
         narrow_filename_size,
951
0
         libclocale_codepage,
952
0
         utf8_filename,
953
0
         utf8_filename_size,
954
0
         error ) != 1 )
955
0
    {
956
0
      libcerror_error_set(
957
0
       error,
958
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
959
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
960
0
       "%s: unable to retrieve narrow extent filename.",
961
0
       function );
962
963
0
      goto on_error;
964
0
    }
965
0
  }
966
0
  extent_data_filename = narrow_string_search_character_reverse(
967
0
                          narrow_filename,
968
0
                          (int) LIBCPATH_SEPARATOR,
969
0
                          narrow_filename_size );
970
971
0
  if( extent_data_filename != NULL )
972
0
  {
973
    /* Ignore the path separator itself
974
     */
975
0
    extent_data_filename++;
976
977
0
    extent_data_filename_size = (size_t) ( extent_data_filename - narrow_filename );
978
0
  }
979
0
  else
980
0
  {
981
0
    extent_data_filename      = narrow_filename;
982
0
    extent_data_filename_size = narrow_filename_size;
983
0
  }
984
0
  if( libvmdk_extent_table_join_extent_data_file_path(
985
0
       extent_table,
986
0
       extent_data_filename,
987
0
       extent_data_filename_size,
988
0
       path,
989
0
       path_size,
990
0
       error ) != 1 )
991
0
  {
992
0
    libcerror_error_set(
993
0
     error,
994
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
995
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
996
0
     "%s: unable to join extent data file path.",
997
0
     function );
998
999
0
    goto on_error;
1000
0
  }
1001
0
  memory_free(
1002
0
   narrow_filename );
1003
1004
0
  return( 1 );
1005
1006
0
on_error:
1007
0
  if( narrow_filename != NULL )
1008
0
  {
1009
0
    memory_free(
1010
0
     narrow_filename );
1011
0
  }
1012
0
  if( utf8_filename != NULL )
1013
0
  {
1014
0
    memory_free(
1015
0
     utf8_filename );
1016
0
  }
1017
0
  return( -1 );
1018
0
}
1019
1020
/* Joins an extent data filename with the data files path
1021
 * Returns 1 if successful or -1 on error
1022
 */
1023
int libvmdk_extent_table_join_extent_data_file_path(
1024
     libvmdk_extent_table_t *extent_table,
1025
     const char *extent_data_filename,
1026
     size_t extent_data_filename_size,
1027
     char **path,
1028
     size_t *path_size,
1029
     libcerror_error_t **error )
1030
0
{
1031
0
  static char *function              = "libvmdk_extent_table_join_extent_data_file_path";
1032
0
  char *narrow_data_files_path       = NULL;
1033
0
  char *safe_path                    = NULL;
1034
0
  size_t narrow_data_files_path_size = 0;
1035
0
  size_t safe_path_size              = 0;
1036
1037
0
  if( extent_table == NULL )
1038
0
  {
1039
0
    libcerror_error_set(
1040
0
     error,
1041
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1042
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1043
0
     "%s: invalid extent table.",
1044
0
     function );
1045
1046
0
    return( -1 );
1047
0
  }
1048
0
  if( extent_data_filename == NULL )
1049
0
  {
1050
0
    libcerror_error_set(
1051
0
     error,
1052
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1053
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1054
0
     "%s: invalid extent data filename.",
1055
0
     function );
1056
1057
0
    return( -1 );
1058
0
  }
1059
0
  if( path == NULL )
1060
0
  {
1061
0
    libcerror_error_set(
1062
0
     error,
1063
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1064
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1065
0
     "%s: invalid path.",
1066
0
     function );
1067
1068
0
    return( -1 );
1069
0
  }
1070
0
  if( path_size == NULL )
1071
0
  {
1072
0
    libcerror_error_set(
1073
0
     error,
1074
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1075
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1076
0
     "%s: invalid path size.",
1077
0
     function );
1078
1079
0
    return( -1 );
1080
0
  }
1081
0
  if( extent_table->data_files_path == NULL )
1082
0
  {
1083
0
    if( ( extent_data_filename_size == 0 )
1084
0
     || ( extent_data_filename_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( char ) ) ) )
1085
0
    {
1086
0
      libcerror_error_set(
1087
0
       error,
1088
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1089
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1090
0
       "%s: invalid extent data filename size value out of bounds.",
1091
0
       function );
1092
1093
0
      goto on_error;
1094
0
    }
1095
0
    safe_path = narrow_string_allocate(
1096
0
                 extent_data_filename_size );
1097
1098
0
    if( safe_path == NULL )
1099
0
    {
1100
0
      libcerror_error_set(
1101
0
       error,
1102
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1103
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1104
0
       "%s: unable to create path.",
1105
0
       function );
1106
1107
0
      goto on_error;
1108
0
    }
1109
0
    safe_path_size = extent_data_filename_size;
1110
1111
0
    if( narrow_string_copy(
1112
0
         safe_path,
1113
0
         extent_data_filename,
1114
0
         extent_data_filename_size ) == NULL )
1115
0
    {
1116
0
      libcerror_error_set(
1117
0
       error,
1118
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1119
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1120
0
       "%s: unable to copy path.",
1121
0
       function );
1122
1123
0
      goto on_error;
1124
0
    }
1125
0
    safe_path[ safe_path_size - 1 ] = 0;
1126
0
  }
1127
0
  else
1128
0
  {
1129
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1130
    if( libvmdk_extent_table_get_data_files_path_size(
1131
         extent_table,
1132
         &narrow_data_files_path_size,
1133
         error ) != 1)
1134
    {
1135
      libcerror_error_set(
1136
       error,
1137
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1138
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1139
       "%s: unable to retrieve narrow data files path size.",
1140
       function );
1141
1142
      goto on_error;
1143
    }
1144
    if( ( narrow_data_files_path_size == 0 )
1145
     || ( narrow_data_files_path_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( char ) ) ) )
1146
    {
1147
      libcerror_error_set(
1148
       error,
1149
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1150
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1151
       "%s: invalid narrow data files path size value out of bounds.",
1152
       function );
1153
1154
      goto on_error;
1155
    }
1156
    narrow_data_files_path = narrow_string_allocate(
1157
                              narrow_data_files_path_size );
1158
1159
    if( narrow_data_files_path == NULL )
1160
    {
1161
      libcerror_error_set(
1162
       error,
1163
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1164
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1165
       "%s: unable to create narrow data files path.",
1166
       function );
1167
1168
      goto on_error;
1169
    }
1170
    if( libvmdk_extent_table_get_data_files_path(
1171
         extent_table,
1172
         narrow_data_files_path,
1173
         narrow_data_files_path_size,
1174
         error ) != 1 )
1175
    {
1176
      libcerror_error_set(
1177
       error,
1178
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1179
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1180
       "%s: unable to retrieve narrow data file path.",
1181
       function );
1182
1183
      goto on_error;
1184
    }
1185
#else
1186
0
    narrow_data_files_path      = (char *) extent_table->data_files_path;
1187
0
    narrow_data_files_path_size = extent_table->data_files_path_size;
1188
1189
0
#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
1190
1191
0
    if( libcpath_path_join(
1192
0
         &safe_path,
1193
0
         &safe_path_size,
1194
0
         narrow_data_files_path,
1195
0
         narrow_data_files_path_size - 1,
1196
0
         extent_data_filename,
1197
0
         extent_data_filename_size - 1,
1198
0
         error ) != 1 )
1199
0
    {
1200
0
      libcerror_error_set(
1201
0
       error,
1202
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1203
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1204
0
       "%s: unable to create path.",
1205
0
       function );
1206
1207
0
      goto on_error;
1208
0
    }
1209
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1210
    memory_free(
1211
     narrow_data_files_path );
1212
#endif
1213
0
  }
1214
0
  *path      = safe_path;
1215
0
  *path_size = safe_path_size;
1216
1217
0
  return( 1 );
1218
1219
0
on_error:
1220
0
  if( safe_path != NULL )
1221
0
  {
1222
0
    memory_free(
1223
0
     safe_path );
1224
0
  }
1225
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1226
  if( narrow_data_files_path != NULL )
1227
  {
1228
    memory_free(
1229
     narrow_data_files_path );
1230
  }
1231
#endif
1232
0
  return( -1 );
1233
0
}
1234
1235
#if defined( HAVE_WIDE_CHARACTER_TYPE )
1236
1237
/* Retrieves the path of an extent data file 
1238
 * Returns 1 if successful or -1 on error
1239
 */
1240
int libvmdk_extent_table_get_extent_data_file_path_wide(
1241
     libvmdk_extent_table_t *extent_table,
1242
     libvmdk_extent_values_t *extent_values,
1243
     wchar_t **path,
1244
     size_t *path_size,
1245
     libcerror_error_t **error )
1246
{
1247
  uint8_t *utf8_filename           = NULL;
1248
  wchar_t *extent_data_filename    = NULL;
1249
  wchar_t *wide_filename           = NULL;
1250
  static char *function            = "libvmdk_extent_table_get_extent_data_file_path_wide";
1251
  size_t extent_data_filename_size = 0;
1252
  size_t utf8_filename_size        = 0;
1253
  size_t wide_filename_size        = 0;
1254
  int result                       = 0;
1255
1256
  if( extent_table == NULL )
1257
  {
1258
    libcerror_error_set(
1259
     error,
1260
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1261
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1262
     "%s: invalid extent table.",
1263
     function );
1264
1265
    return( -1 );
1266
  }
1267
  if( extent_values == NULL )
1268
  {
1269
    libcerror_error_set(
1270
     error,
1271
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1272
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1273
     "%s: invalid extent values.",
1274
     function );
1275
1276
    return( -1 );
1277
  }
1278
  if( path == NULL )
1279
  {
1280
    libcerror_error_set(
1281
     error,
1282
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1283
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1284
     "%s: invalid path.",
1285
     function );
1286
1287
    return( -1 );
1288
  }
1289
  if( path_size == NULL )
1290
  {
1291
    libcerror_error_set(
1292
     error,
1293
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1294
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1295
     "%s: invalid path size.",
1296
     function );
1297
1298
    return( -1 );
1299
  }
1300
  if( libvmdk_extent_values_get_utf8_filename_size(
1301
       extent_values,
1302
       &utf8_filename_size,
1303
       error ) != 1 )
1304
  {
1305
    libcerror_error_set(
1306
     error,
1307
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1308
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1309
     "%s: unable to retrieve UTF-8 extent filename size.",
1310
     function );
1311
1312
    goto on_error;
1313
  }
1314
  if( ( utf8_filename_size == 0 )
1315
   || ( utf8_filename_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
1316
  {
1317
    libcerror_error_set(
1318
     error,
1319
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1320
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1321
     "%s: invalid UTF-8 extent filename size value out of bounds.",
1322
     function );
1323
1324
    goto on_error;
1325
  }
1326
  utf8_filename = (uint8_t *) memory_allocate(
1327
                               sizeof( uint8_t ) * utf8_filename_size );
1328
1329
  if( utf8_filename == NULL )
1330
  {
1331
    libcerror_error_set(
1332
     error,
1333
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1334
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1335
     "%s: unable to create UTF-8 extent filename.",
1336
     function );
1337
1338
    goto on_error;
1339
  }
1340
  if( libvmdk_extent_values_get_utf8_filename(
1341
       extent_values,
1342
       utf8_filename,
1343
       utf8_filename_size,
1344
       error ) != 1 )
1345
  {
1346
    libcerror_error_set(
1347
     error,
1348
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1349
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1350
     "%s: unable to retrieve UTF-8 extent filename.",
1351
     function );
1352
1353
    goto on_error;
1354
  }
1355
#if SIZEOF_WCHAR_T == 4
1356
  result = libuna_utf32_string_size_from_utf8(
1357
            utf8_filename,
1358
            utf8_filename_size,
1359
            &wide_filename_size,
1360
            error );
1361
#elif SIZEOF_WCHAR_T == 2
1362
  result = libuna_utf16_string_size_from_utf8(
1363
            utf8_filename,
1364
            utf8_filename_size,
1365
            &wide_filename_size,
1366
            error );
1367
#else
1368
#error Unsupported size of wchar_t
1369
#endif /* SIZEOF_WCHAR_T */
1370
1371
  if( result != 1 )
1372
  {
1373
    libcerror_error_set(
1374
     error,
1375
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1376
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1377
     "%s: unable to retrieve wide extent filename size.",
1378
     function );
1379
1380
    goto on_error;
1381
  }
1382
  if( ( wide_filename_size == 0 )
1383
   || ( wide_filename_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( wchar_t ) ) ) )
1384
  {
1385
    libcerror_error_set(
1386
     error,
1387
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1388
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1389
     "%s: invalid wide extent filename size value out of bounds.",
1390
     function );
1391
1392
    goto on_error;
1393
  }
1394
  wide_filename = wide_string_allocate(
1395
                   wide_filename_size );
1396
1397
  if( wide_filename == NULL )
1398
  {
1399
    libcerror_error_set(
1400
     error,
1401
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1402
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1403
     "%s: unable to create wide extent filename.",
1404
     function );
1405
1406
    goto on_error;
1407
  }
1408
#if SIZEOF_WCHAR_T == 4
1409
  result = libuna_utf32_string_copy_from_utf8(
1410
            (libuna_utf32_character_t *) wide_filename,
1411
            wide_filename_size,
1412
            utf8_filename,
1413
            utf8_filename_size,
1414
            error );
1415
#elif SIZEOF_WCHAR_T == 2
1416
  result = libuna_utf16_string_copy_from_utf8(
1417
            (libuna_utf16_character_t *) wide_filename,
1418
            wide_filename_size,
1419
            utf8_filename,
1420
            utf8_filename_size,
1421
            error );
1422
#else
1423
#error Unsupported size of wchar_t
1424
#endif /* SIZEOF_WCHAR_T */
1425
1426
  if( result != 1 )
1427
  {
1428
    libcerror_error_set(
1429
     error,
1430
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1431
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1432
     "%s: unable to retrieve wide extent filename.",
1433
     function );
1434
1435
    goto on_error;
1436
  }
1437
  memory_free(
1438
   utf8_filename );
1439
1440
  utf8_filename = NULL;
1441
1442
  extent_data_filename = wide_string_search_character_reverse(
1443
                          wide_filename,
1444
                          (wint_t) LIBCPATH_SEPARATOR,
1445
                          wide_filename_size );
1446
1447
  if( extent_data_filename != NULL )
1448
  {
1449
    /* Ignore the path separator itself
1450
     */
1451
    extent_data_filename++;
1452
1453
    extent_data_filename_size = (size_t) ( extent_data_filename - wide_filename );
1454
  }
1455
  else
1456
  {
1457
    extent_data_filename      = wide_filename;
1458
    extent_data_filename_size = wide_filename_size;
1459
  }
1460
  if( libvmdk_extent_table_join_extent_data_file_path_wide(
1461
       extent_table,
1462
       extent_data_filename,
1463
       extent_data_filename_size,
1464
       path,
1465
       path_size,
1466
       error ) != 1 )
1467
  {
1468
    libcerror_error_set(
1469
     error,
1470
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1471
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1472
     "%s: unable to join extent data file path.",
1473
     function );
1474
1475
    goto on_error;
1476
  }
1477
  memory_free(
1478
   wide_filename );
1479
1480
  return( 1 );
1481
1482
on_error:
1483
  if( wide_filename != NULL )
1484
  {
1485
    memory_free(
1486
     wide_filename );
1487
  }
1488
  if( utf8_filename != NULL )
1489
  {
1490
    memory_free(
1491
     utf8_filename );
1492
  }
1493
  return( -1 );
1494
}
1495
1496
/* Joins an extent data filename with the data files path
1497
 * Returns 1 if successful or -1 on error
1498
 */
1499
int libvmdk_extent_table_join_extent_data_file_path_wide(
1500
     libvmdk_extent_table_t *extent_table,
1501
     const wchar_t *extent_data_filename,
1502
     size_t extent_data_filename_size,
1503
     wchar_t **path,
1504
     size_t *path_size,
1505
     libcerror_error_t **error )
1506
{
1507
  wchar_t *safe_path               = NULL;
1508
  wchar_t *wide_data_files_path    = NULL;
1509
  static char *function            = "libvmdk_extent_table_join_extent_data_file_path_wide";
1510
  size_t safe_path_size            = 0;
1511
  size_t wide_data_files_path_size = 0;
1512
1513
  if( extent_table == NULL )
1514
  {
1515
    libcerror_error_set(
1516
     error,
1517
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1518
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1519
     "%s: invalid extent table.",
1520
     function );
1521
1522
    return( -1 );
1523
  }
1524
  if( extent_data_filename == NULL )
1525
  {
1526
    libcerror_error_set(
1527
     error,
1528
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1529
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1530
     "%s: invalid extent data filename.",
1531
     function );
1532
1533
    return( -1 );
1534
  }
1535
  if( path == NULL )
1536
  {
1537
    libcerror_error_set(
1538
     error,
1539
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1540
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1541
     "%s: invalid path.",
1542
     function );
1543
1544
    return( -1 );
1545
  }
1546
  if( path_size == NULL )
1547
  {
1548
    libcerror_error_set(
1549
     error,
1550
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1551
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1552
     "%s: invalid path size.",
1553
     function );
1554
1555
    return( -1 );
1556
  }
1557
  if( extent_table->data_files_path == NULL )
1558
  {
1559
    if( ( extent_data_filename_size == 0 )
1560
     || ( extent_data_filename_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( wchar_t ) ) ) )
1561
    {
1562
      libcerror_error_set(
1563
       error,
1564
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1565
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1566
       "%s: invalid extent data filename size value out of bounds.",
1567
       function );
1568
1569
      goto on_error;
1570
    }
1571
    safe_path = wide_string_allocate(
1572
                 extent_data_filename_size );
1573
1574
    if( safe_path == NULL )
1575
    {
1576
      libcerror_error_set(
1577
       error,
1578
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1579
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1580
       "%s: unable to create path.",
1581
       function );
1582
1583
      goto on_error;
1584
    }
1585
    safe_path_size = extent_data_filename_size;
1586
1587
    if( wide_string_copy(
1588
         safe_path,
1589
         extent_data_filename,
1590
         extent_data_filename_size ) == NULL )
1591
    {
1592
      libcerror_error_set(
1593
       error,
1594
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1595
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1596
       "%s: unable to copy path.",
1597
       function );
1598
1599
      goto on_error;
1600
    }
1601
    safe_path[ safe_path_size - 1 ] = 0;
1602
  }
1603
  else
1604
  {
1605
#if !defined( HAVE_WIDE_SYSTEM_CHARACTER )
1606
    if( libvmdk_extent_table_get_data_files_path_size_wide(
1607
         extent_table,
1608
         &wide_data_files_path_size,
1609
         error ) != 1)
1610
    {
1611
      libcerror_error_set(
1612
       error,
1613
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1614
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1615
       "%s: unable to retrieve wide data files path size.",
1616
       function );
1617
1618
      goto on_error;
1619
    }
1620
    if( ( wide_data_files_path_size == 0 )
1621
     || ( wide_data_files_path_size > ( MEMORY_MAXIMUM_ALLOCATION_SIZE / sizeof( wchar_t ) ) ) )
1622
    {
1623
      libcerror_error_set(
1624
       error,
1625
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1626
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1627
       "%s: invalid wide data files path size value out of bounds.",
1628
       function );
1629
1630
      goto on_error;
1631
    }
1632
    wide_data_files_path = wide_string_allocate(
1633
                            wide_data_files_path_size );
1634
1635
    if( wide_data_files_path == NULL )
1636
    {
1637
      libcerror_error_set(
1638
       error,
1639
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1640
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1641
       "%s: unable to create wide data files path.",
1642
       function );
1643
1644
      goto on_error;
1645
    }
1646
    if( libvmdk_extent_table_get_data_files_path_wide(
1647
         extent_table,
1648
         wide_data_files_path,
1649
         wide_data_files_path_size,
1650
         error ) != 1 )
1651
    {
1652
      libcerror_error_set(
1653
       error,
1654
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1655
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1656
       "%s: unable to retrieve wide data file path.",
1657
       function );
1658
1659
      goto on_error;
1660
    }
1661
#else
1662
    wide_data_files_path      = (wchar_t *) extent_table->data_files_path;
1663
    wide_data_files_path_size = extent_table->data_files_path_size;
1664
1665
#endif /* !defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
1666
1667
    if( libcpath_path_join_wide(
1668
         &safe_path,
1669
         &safe_path_size,
1670
         wide_data_files_path,
1671
         wide_data_files_path_size - 1,
1672
         extent_data_filename,
1673
         extent_data_filename_size - 1,
1674
         error ) != 1 )
1675
    {
1676
      libcerror_error_set(
1677
       error,
1678
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1679
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1680
       "%s: unable to create path.",
1681
       function );
1682
1683
      goto on_error;
1684
    }
1685
#if !defined( HAVE_WIDE_SYSTEM_CHARACTER )
1686
    memory_free(
1687
     wide_data_files_path );
1688
#endif
1689
  }
1690
  *path      = safe_path;
1691
  *path_size = safe_path_size;
1692
1693
  return( 1 );
1694
1695
on_error:
1696
  if( safe_path != NULL )
1697
  {
1698
    memory_free(
1699
     safe_path );
1700
  }
1701
#if !defined( HAVE_WIDE_SYSTEM_CHARACTER )
1702
  if( wide_data_files_path != NULL )
1703
  {
1704
    memory_free(
1705
     wide_data_files_path );
1706
  }
1707
#endif
1708
  return( -1 );
1709
}
1710
1711
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1712
1713
/* Initializes the extents
1714
 * Returns 1 if successful or -1 on error
1715
 */
1716
int libvmdk_extent_table_initialize_extents(
1717
     libvmdk_extent_table_t *extent_table,
1718
     int number_of_extents,
1719
     int disk_type,
1720
     libcerror_error_t **error )
1721
0
{
1722
0
  static char *function = "libvmdk_extent_table_initialize_extents";
1723
0
  int result            = 0;
1724
1725
0
  if( extent_table == NULL )
1726
0
  {
1727
0
    libcerror_error_set(
1728
0
     error,
1729
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1730
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1731
0
     "%s: invalid extent table.",
1732
0
     function );
1733
1734
0
    return( -1 );
1735
0
  }
1736
0
  if( ( disk_type != LIBVMDK_DISK_TYPE_FLAT_2GB_EXTENT )
1737
0
   && ( disk_type != LIBVMDK_DISK_TYPE_MONOLITHIC_FLAT )
1738
0
   && ( disk_type != LIBVMDK_DISK_TYPE_SPARSE_2GB_EXTENT )
1739
0
   && ( disk_type != LIBVMDK_DISK_TYPE_MONOLITHIC_SPARSE )
1740
0
   && ( disk_type != LIBVMDK_DISK_TYPE_STREAM_OPTIMIZED )
1741
0
   && ( disk_type != LIBVMDK_DISK_TYPE_VMFS_FLAT )
1742
0
   && ( disk_type != LIBVMDK_DISK_TYPE_VMFS_FLAT_PRE_ALLOCATED )
1743
0
   && ( disk_type != LIBVMDK_DISK_TYPE_VMFS_FLAT_ZEROED )
1744
0
   && ( disk_type != LIBVMDK_DISK_TYPE_VMFS_SPARSE )
1745
0
   && ( disk_type != LIBVMDK_DISK_TYPE_VMFS_SPARSE_THIN ) )
1746
0
  {
1747
0
    libcerror_error_set(
1748
0
     error,
1749
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1750
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1751
0
     "%s: unsupported disk type.",
1752
0
     function );
1753
1754
0
    return( -1 );
1755
0
  }
1756
0
  if( ( disk_type == LIBVMDK_DISK_TYPE_FLAT_2GB_EXTENT )
1757
0
   || ( disk_type == LIBVMDK_DISK_TYPE_MONOLITHIC_FLAT )
1758
0
   || ( disk_type == LIBVMDK_DISK_TYPE_VMFS_FLAT )
1759
0
   || ( disk_type == LIBVMDK_DISK_TYPE_VMFS_FLAT_PRE_ALLOCATED )
1760
0
   || ( disk_type == LIBVMDK_DISK_TYPE_VMFS_FLAT_ZEROED ) )
1761
0
  {
1762
0
    result = libfdata_stream_initialize(
1763
0
              &( extent_table->extent_files_stream ),
1764
0
              (intptr_t *) extent_table->io_handle,
1765
0
              NULL,
1766
0
              NULL,
1767
0
              NULL,
1768
0
              (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libvmdk_extent_file_read_segment_data,
1769
0
              NULL,
1770
0
              (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libvmdk_extent_file_seek_segment_offset,
1771
0
              LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
1772
0
              error );
1773
1774
0
    if( result != 1 )
1775
0
    {
1776
0
      libcerror_error_set(
1777
0
       error,
1778
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1779
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1780
0
       "%s: unable to create extent files stream.",
1781
0
       function );
1782
1783
0
      goto on_error;
1784
0
    }
1785
0
    if( libfdata_stream_resize(
1786
0
         extent_table->extent_files_stream,
1787
0
         number_of_extents,
1788
0
         error ) != 1 )
1789
0
    {
1790
0
      libcerror_error_set(
1791
0
       error,
1792
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1793
0
       LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
1794
0
       "%s: unable to resize extents file stream.",
1795
0
       function );
1796
1797
0
      goto on_error;
1798
0
    }
1799
0
  }
1800
0
  else if( ( disk_type == LIBVMDK_DISK_TYPE_SPARSE_2GB_EXTENT )
1801
0
        || ( disk_type == LIBVMDK_DISK_TYPE_MONOLITHIC_SPARSE )
1802
0
        || ( disk_type == LIBVMDK_DISK_TYPE_STREAM_OPTIMIZED )
1803
0
        || ( disk_type == LIBVMDK_DISK_TYPE_VMFS_SPARSE )
1804
0
        || ( disk_type == LIBVMDK_DISK_TYPE_VMFS_SPARSE_THIN ) )
1805
0
  {
1806
0
    result = libfdata_list_initialize(
1807
0
              &( extent_table->extent_files_list ),
1808
0
              (intptr_t *) extent_table->io_handle,
1809
0
              NULL,
1810
0
              NULL,
1811
0
              (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libvmdk_extent_file_read_element_data,
1812
0
              NULL,
1813
0
              LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
1814
0
              error );
1815
1816
0
    if( result != 1 )
1817
0
    {
1818
0
      libcerror_error_set(
1819
0
       error,
1820
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1821
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1822
0
       "%s: unable to create extent files list.",
1823
0
       function );
1824
1825
0
      goto on_error;
1826
0
    }
1827
0
    if( libfdata_list_resize(
1828
0
         extent_table->extent_files_list,
1829
0
         number_of_extents,
1830
0
         error ) != 1 )
1831
0
    {
1832
0
      libcerror_error_set(
1833
0
       error,
1834
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1835
0
       LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
1836
0
       "%s: unable to resize extent files list.",
1837
0
       function );
1838
1839
0
      goto on_error;
1840
0
    }
1841
0
    result = libfcache_cache_initialize(
1842
0
        &( extent_table->extent_files_cache ),
1843
0
        LIBVMDK_MAXIMUM_CACHE_ENTRIES_EXTENT_FILES,
1844
0
        error );
1845
1846
0
    if( result != 1 )
1847
0
    {
1848
0
      libcerror_error_set(
1849
0
       error,
1850
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1851
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1852
0
       "%s: unable to create extent files cache.",
1853
0
       function );
1854
1855
0
      goto on_error;
1856
0
    }
1857
0
  }
1858
0
  extent_table->number_of_extents = number_of_extents;
1859
0
  extent_table->disk_type         = disk_type;
1860
1861
0
  return( 1 );
1862
1863
0
on_error:
1864
0
  if( extent_table->extent_files_list != NULL )
1865
0
  {
1866
0
    libfdata_list_free(
1867
0
     &( extent_table->extent_files_list ),
1868
0
     NULL );
1869
0
  }
1870
0
  if( extent_table->extent_files_stream != NULL )
1871
0
  {
1872
0
    libfdata_stream_free(
1873
0
     &( extent_table->extent_files_stream ),
1874
0
     NULL );
1875
0
  }
1876
0
  return( -1 );
1877
0
}
1878
1879
/* Sets the extent storage media size for a specific extent in the extent table
1880
 * Returns 1 if successful or -1 on error
1881
 */
1882
int libvmdk_extent_table_set_extent_storage_media_size_by_index(
1883
     libvmdk_extent_table_t *extent_table,
1884
     int extent_index,
1885
     size64_t storage_media_size,
1886
     libcerror_error_t **error )
1887
0
{
1888
0
  static char *function = "libvmdk_extent_table_set_extent_storage_media_size_by_index";
1889
1890
0
  if( extent_table == 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 extent table.",
1897
0
     function );
1898
1899
0
    return( -1 );
1900
0
  }
1901
0
  if( libfdata_list_set_mapped_size_by_index(
1902
0
       extent_table->extent_files_list,
1903
0
       extent_index,
1904
0
       storage_media_size,
1905
0
       error ) != 1 )
1906
0
  {
1907
0
    libcerror_error_set(
1908
0
     error,
1909
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1910
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1911
0
     "%s: unable to set mapped size of element: %d in extent files list.",
1912
0
     function,
1913
0
     extent_index );
1914
1915
0
    return( -1 );
1916
0
  }
1917
0
  return( 1 );
1918
0
}
1919
1920
/* Retrieves an extent file at a specific offset from the extent table
1921
 * Returns 1 if successful or -1 on error
1922
 */
1923
int libvmdk_extent_table_get_extent_file_at_offset(
1924
     libvmdk_extent_table_t *extent_table,
1925
     off64_t offset,
1926
     libbfio_pool_t *file_io_pool,
1927
     int *extent_index,
1928
     off64_t *extent_file_data_offset,
1929
     libvmdk_extent_file_t **extent_file,
1930
     libcerror_error_t **error )
1931
0
{
1932
0
  static char *function = "libvmdk_extent_table_get_extent_file_at_offset";
1933
1934
0
  if( extent_table == NULL )
1935
0
  {
1936
0
    libcerror_error_set(
1937
0
     error,
1938
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1939
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1940
0
     "%s: invalid extent table.",
1941
0
     function );
1942
1943
0
    return( -1 );
1944
0
  }
1945
0
  if( libfdata_list_get_element_value_at_offset(
1946
0
       extent_table->extent_files_list,
1947
0
       (intptr_t *) file_io_pool,
1948
0
       (libfdata_cache_t *) extent_table->extent_files_cache,
1949
0
       offset,
1950
0
       extent_index,
1951
0
       extent_file_data_offset,
1952
0
       (intptr_t **) extent_file,
1953
0
       0,
1954
0
       error ) != 1 )
1955
0
  {
1956
0
    libcerror_error_set(
1957
0
     error,
1958
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1959
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1960
0
     "%s: unable to retrieve element at offset: %" PRIi64 " (0x%08" PRIx64 ") from extent files list.",
1961
0
     function,
1962
0
     offset,
1963
0
     offset );
1964
1965
0
    return( -1 );
1966
0
  }
1967
0
  return( 1 );
1968
0
}
1969
1970
/* Sets an extent in the extent table based on the extent values
1971
 * Returns 1 if successful or -1 on error
1972
 */
1973
int libvmdk_extent_table_set_extent_by_extent_values(
1974
     libvmdk_extent_table_t *extent_table,
1975
     libvmdk_extent_values_t *extent_values,
1976
     int extent_index,
1977
     int file_io_pool_entry,
1978
     size64_t extent_file_size,
1979
     off64_t extent_offset,
1980
     size64_t extent_size,
1981
     libcerror_error_t **error )
1982
0
{
1983
0
  static char *function = "libvmdk_extent_table_set_extent_by_extent_values";
1984
1985
0
  if( extent_table == NULL )
1986
0
  {
1987
0
    libcerror_error_set(
1988
0
     error,
1989
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1990
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1991
0
     "%s: invalid extent table.",
1992
0
     function );
1993
1994
0
    return( -1 );
1995
0
  }
1996
0
  if( extent_values == NULL )
1997
0
  {
1998
0
    libcerror_error_set(
1999
0
     error,
2000
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2001
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2002
0
     "%s: invalid extent values.",
2003
0
     function );
2004
2005
0
    return( -1 );
2006
0
  }
2007
0
  if( ( extent_index < 0 )
2008
0
   || ( extent_index > extent_table->number_of_extents ) )
2009
0
  {
2010
0
    libcerror_error_set(
2011
0
     error,
2012
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2013
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2014
0
     "%s: invalid extent index value out of bounds.",
2015
0
     function );
2016
2017
0
    return( -1 );
2018
0
  }
2019
0
  if( extent_index == 0 )
2020
0
  {
2021
0
    if( extent_values->type == LIBVMDK_EXTENT_TYPE_FLAT )
2022
0
    {
2023
0
      if( ( extent_table->disk_type != LIBVMDK_DISK_TYPE_FLAT_2GB_EXTENT )
2024
0
       && ( extent_table->disk_type != LIBVMDK_DISK_TYPE_MONOLITHIC_FLAT ) )
2025
0
      {
2026
0
        libcerror_error_set(
2027
0
         error,
2028
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2029
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2030
0
         "%s: extent type not supported for disk type.",
2031
0
         function );
2032
2033
0
        return( -1 );
2034
0
      }
2035
0
    }
2036
0
    else if( extent_values->type == LIBVMDK_EXTENT_TYPE_SPARSE )
2037
0
    {
2038
0
      if( ( extent_table->disk_type != LIBVMDK_DISK_TYPE_SPARSE_2GB_EXTENT )
2039
0
       && ( extent_table->disk_type != LIBVMDK_DISK_TYPE_MONOLITHIC_SPARSE )
2040
0
       && ( extent_table->disk_type != LIBVMDK_DISK_TYPE_STREAM_OPTIMIZED ) )
2041
0
      {
2042
0
        libcerror_error_set(
2043
0
         error,
2044
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2045
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2046
0
         "%s: extent type not supported for disk type.",
2047
0
         function );
2048
2049
0
        return( -1 );
2050
0
      }
2051
0
    }
2052
0
    else if( extent_values->type == LIBVMDK_EXTENT_TYPE_VMFS_FLAT )
2053
0
    {
2054
0
      if( ( extent_table->disk_type != LIBVMDK_DISK_TYPE_VMFS_FLAT )
2055
0
       && ( extent_table->disk_type != LIBVMDK_DISK_TYPE_VMFS_FLAT_PRE_ALLOCATED )
2056
0
       && ( extent_table->disk_type != LIBVMDK_DISK_TYPE_VMFS_FLAT_ZEROED ) )
2057
0
      {
2058
0
        libcerror_error_set(
2059
0
         error,
2060
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2061
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2062
0
         "%s: extent type not supported for disk type.",
2063
0
         function );
2064
2065
0
        return( -1 );
2066
0
      }
2067
0
    }
2068
0
    else if( extent_values->type == LIBVMDK_EXTENT_TYPE_VMFS_SPARSE )
2069
0
    {
2070
0
      if( ( extent_table->disk_type != LIBVMDK_DISK_TYPE_VMFS_SPARSE )
2071
0
       && ( extent_table->disk_type != LIBVMDK_DISK_TYPE_VMFS_SPARSE_THIN ) )
2072
0
      {
2073
0
        libcerror_error_set(
2074
0
         error,
2075
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2076
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2077
0
         "%s: extent type not supported for disk type.",
2078
0
         function );
2079
2080
0
        return( -1 );
2081
0
      }
2082
0
    }
2083
0
    else
2084
0
    {
2085
0
      libcerror_error_set(
2086
0
       error,
2087
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2088
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2089
0
       "%s: unsupported extent type.",
2090
0
       function );
2091
2092
0
      return( -1 );
2093
0
    }
2094
0
    extent_table->extent_type = extent_values->type;
2095
0
  }
2096
0
  else if( extent_table->extent_type != extent_values->type )
2097
0
  {
2098
0
    libcerror_error_set(
2099
0
     error,
2100
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2101
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2102
0
     "%s: mixed extent types not supported.",
2103
0
     function );
2104
2105
0
    return( -1 );
2106
0
  }
2107
0
  if( ( extent_values->type == LIBVMDK_EXTENT_TYPE_FLAT )
2108
0
   || ( extent_values->type == LIBVMDK_EXTENT_TYPE_VMFS_FLAT ) )
2109
0
  {
2110
0
    if( ( extent_offset < 0 )
2111
0
     || ( (size64_t) extent_offset >= extent_file_size ) )
2112
0
    {
2113
0
      libcerror_error_set(
2114
0
       error,
2115
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2116
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2117
0
       "%s: invalid extent offset value out of bounds.",
2118
0
       function );
2119
2120
0
      return( -1 );
2121
0
    }
2122
0
    if( extent_size > ( extent_file_size - (size64_t) extent_offset ) )
2123
0
    {
2124
0
      libcerror_error_set(
2125
0
       error,
2126
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2127
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2128
0
       "%s: invalid extent size value out of bounds.",
2129
0
       function );
2130
2131
0
      return( -1 );
2132
0
    }
2133
0
    if( libfdata_stream_set_segment_by_index(
2134
0
         extent_table->extent_files_stream,
2135
0
         extent_index,
2136
0
         file_io_pool_entry,
2137
0
         extent_offset,
2138
0
         extent_size,
2139
0
         0,
2140
0
         error ) != 1 )
2141
0
    {
2142
0
      libcerror_error_set(
2143
0
       error,
2144
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2145
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2146
0
       "%s: unable to set segment: %d in extent files stream.",
2147
0
       function,
2148
0
       extent_index );
2149
2150
0
      return( -1 );
2151
0
    }
2152
0
  }
2153
0
  else if( ( extent_values->type == LIBVMDK_EXTENT_TYPE_SPARSE )
2154
0
        || ( extent_values->type == LIBVMDK_EXTENT_TYPE_VMFS_SPARSE ) )
2155
0
  {
2156
0
    if( extent_offset != 0 )
2157
0
    {
2158
0
      libcerror_error_set(
2159
0
       error,
2160
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2161
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2162
0
       "%s: invalid extent offset value out of bounds.",
2163
0
       function );
2164
2165
0
      return( -1 );
2166
0
    }
2167
0
    if( libfdata_list_set_element_by_index_with_mapped_size(
2168
0
         extent_table->extent_files_list,
2169
0
         extent_index,
2170
0
         file_io_pool_entry,
2171
0
         0,
2172
0
         extent_file_size,
2173
0
         0,
2174
0
         extent_size,
2175
0
         error ) != 1 )
2176
0
    {
2177
0
      libcerror_error_set(
2178
0
       error,
2179
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2180
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2181
0
       "%s: unable to set element: %d in extent files list.",
2182
0
       function,
2183
0
       extent_index );
2184
2185
0
      return( -1 );
2186
0
    }
2187
0
  }
2188
0
  return( 1 );
2189
0
}
2190