Coverage Report

Created: 2026-07-10 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvmdk/libvmdk/libvmdk_descriptor_file.c
Line
Count
Source
1
/*
2
 * Descriptor file functions
3
 *
4
 * Copyright (C) 2009-2026, 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 <file_stream.h>
24
#include <memory.h>
25
#include <narrow_string.h>
26
#include <types.h>
27
28
#include "libvmdk_definitions.h"
29
#include "libvmdk_descriptor_file.h"
30
#include "libvmdk_extent_values.h"
31
#include "libvmdk_libcdata.h"
32
#include "libvmdk_libcerror.h"
33
#include "libvmdk_libclocale.h"
34
#include "libvmdk_libcnotify.h"
35
#include "libvmdk_libcsplit.h"
36
#include "libvmdk_libfvalue.h"
37
#include "libvmdk_libuna.h"
38
39
const char *vmdk_descriptor_file_signature                       = "# Disk DescriptorFile";
40
const char *vmdk_descriptor_file_extent_section_signature        = "# Extent description";
41
const char *vmdk_descriptor_file_change_tracking_file_signature  = "# Change Tracking File";
42
const char *vmdk_descriptor_file_disk_database_section_signature = "# The Disk Data Base";
43
44
/* Creates a descriptor file
45
 * Make sure the value descriptor_file is referencing, is set to NULL
46
 * Returns 1 if successful or -1 on error
47
 */
48
int libvmdk_descriptor_file_initialize(
49
     libvmdk_descriptor_file_t **descriptor_file,
50
     libcerror_error_t **error )
51
7.62k
{
52
7.62k
  static char *function = "libvmdk_descriptor_file_initialize";
53
54
7.62k
  if( descriptor_file == 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 descriptor file.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
7.62k
  if( *descriptor_file != 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 descriptor file value already set.",
72
0
     function );
73
74
0
    return( -1 );
75
0
  }
76
7.62k
  *descriptor_file = memory_allocate_structure(
77
7.62k
                      libvmdk_descriptor_file_t );
78
79
7.62k
  if( *descriptor_file == NULL )
80
0
  {
81
0
    libcerror_error_set(
82
0
     error,
83
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
84
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
85
0
     "%s: unable to create descriptor file.",
86
0
     function );
87
88
0
    goto on_error;
89
0
  }
90
7.62k
  if( memory_set(
91
7.62k
       *descriptor_file,
92
7.62k
       0,
93
7.62k
       sizeof( libvmdk_descriptor_file_t ) ) == NULL )
94
0
  {
95
0
    libcerror_error_set(
96
0
     error,
97
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
98
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
99
0
     "%s: unable to clear descriptor file.",
100
0
     function );
101
102
0
    memory_free(
103
0
     *descriptor_file );
104
105
0
    *descriptor_file = NULL;
106
107
0
    return( -1 );
108
0
  }
109
7.62k
  return( 1 );
110
111
0
on_error:
112
0
  if( *descriptor_file != NULL )
113
0
  {
114
0
    memory_free(
115
0
     *descriptor_file );
116
117
0
    *descriptor_file = NULL;
118
0
  }
119
0
  return( -1 );
120
7.62k
}
121
122
/* Frees a descriptor file
123
 * Returns 1 if successful or -1 on error
124
 */
125
int libvmdk_descriptor_file_free(
126
     libvmdk_descriptor_file_t **descriptor_file,
127
     libcerror_error_t **error )
128
7.62k
{
129
7.62k
  static char *function = "libvmdk_descriptor_file_free";
130
7.62k
  int result            = 1;
131
132
7.62k
  if( descriptor_file == NULL )
133
0
  {
134
0
    libcerror_error_set(
135
0
     error,
136
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
137
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
138
0
     "%s: invalid descriptor file.",
139
0
     function );
140
141
0
    return( -1 );
142
0
  }
143
7.62k
  if( *descriptor_file != NULL )
144
7.62k
  {
145
7.62k
    if( ( *descriptor_file )->parent_filename != NULL )
146
328
    {
147
328
      memory_free(
148
328
       ( *descriptor_file )->parent_filename );
149
328
    }
150
7.62k
    memory_free(
151
7.62k
     *descriptor_file );
152
153
7.62k
    *descriptor_file = NULL;
154
7.62k
  }
155
7.62k
  return( result );
156
7.62k
}
157
158
/* Reads the descriptor file
159
 * Returns the 1 if successful or -1 on error
160
 */
161
int libvmdk_descriptor_file_read_file_io_handle(
162
     libvmdk_descriptor_file_t *descriptor_file,
163
     libbfio_handle_t *file_io_handle,
164
     libcdata_array_t *extents_values_array,
165
     libcerror_error_t **error )
166
7.40k
{
167
7.40k
  uint8_t *descriptor_data = NULL;
168
7.40k
  static char *function    = "libvmdk_descriptor_file_read_file_io_handle";
169
7.40k
  size64_t file_size       = 0;
170
7.40k
  ssize_t read_count       = 0;
171
172
7.40k
  if( descriptor_file == NULL )
173
0
  {
174
0
    libcerror_error_set(
175
0
     error,
176
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
177
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
178
0
     "%s: invalid descriptor file.",
179
0
     function );
180
181
0
    return( -1 );
182
0
  }
183
7.40k
  if( libbfio_handle_get_size(
184
7.40k
       file_io_handle,
185
7.40k
       &file_size,
186
7.40k
       error ) == -1 )
187
0
  {
188
0
    libcerror_error_set(
189
0
     error,
190
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
191
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
192
0
     "%s: unable to determine size of file IO handle entry.",
193
0
     function );
194
195
0
    goto on_error;
196
0
  }
197
7.40k
  if( ( file_size == 0 )
198
7.40k
   || ( file_size > (size64_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
199
0
  {
200
0
    libcerror_error_set(
201
0
     error,
202
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
203
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
204
0
     "%s: invalid file size value out of bounds.",
205
0
     function );
206
207
0
    goto on_error;
208
0
  }
209
7.40k
  descriptor_data = (uint8_t *) memory_allocate(
210
7.40k
                                 sizeof( uint8_t ) * (size_t) file_size );
211
212
7.40k
  if( descriptor_data == NULL )
213
0
  {
214
0
    libcerror_error_set(
215
0
     error,
216
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
217
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
218
0
     "%s: unable to create descriptor data.",
219
0
     function );
220
221
0
    goto on_error;
222
0
  }
223
7.40k
  read_count = libbfio_handle_read_buffer_at_offset(
224
7.40k
                file_io_handle,
225
7.40k
                descriptor_data,
226
7.40k
                (size_t) file_size,
227
7.40k
                0,
228
7.40k
                error );
229
230
7.40k
  if( read_count != (ssize_t) file_size )
231
0
  {
232
0
    libcerror_error_set(
233
0
     error,
234
0
     LIBCERROR_ERROR_DOMAIN_IO,
235
0
     LIBCERROR_IO_ERROR_READ_FAILED,
236
0
     "%s: unable to read data at offset: 0 (0x00000000).",
237
0
     function );
238
239
0
    goto on_error;
240
0
  }
241
7.40k
  if( libvmdk_descriptor_file_read_string(
242
7.40k
       descriptor_file,
243
7.40k
       (char *) descriptor_data,
244
7.40k
       (size_t) file_size,
245
7.40k
       extents_values_array,
246
7.40k
       error ) != 1 )
247
6.54k
  {
248
6.54k
    libcerror_error_set(
249
6.54k
     error,
250
6.54k
     LIBCERROR_ERROR_DOMAIN_IO,
251
6.54k
     LIBCERROR_IO_ERROR_READ_FAILED,
252
6.54k
     "%s: unable to read descriptor from string.",
253
6.54k
     function );
254
255
6.54k
    goto on_error;
256
6.54k
  }
257
858
  memory_free(
258
858
   descriptor_data );
259
260
858
  descriptor_data = NULL;
261
262
858
  return( 1 );
263
264
6.54k
on_error:
265
6.54k
  if( descriptor_data != NULL )
266
6.54k
  {
267
6.54k
    memory_free(
268
6.54k
     descriptor_data );
269
6.54k
  }
270
6.54k
  return( -1 );
271
7.40k
}
272
273
/* Reads the descriptor file from a string
274
 * Returns the 1 if successful or -1 on error
275
 */
276
int libvmdk_descriptor_file_read_string(
277
     libvmdk_descriptor_file_t *descriptor_file,
278
     const char *value_string,
279
     size_t value_string_size,
280
     libcdata_array_t *extents_values_array,
281
     libcerror_error_t **error )
282
7.41k
{
283
7.41k
  libcsplit_narrow_split_string_t *lines = NULL;
284
7.41k
  static char *function                  = "libvmdk_descriptor_file_read_string";
285
7.41k
  int line_index                         = 0;
286
7.41k
  int number_of_lines                    = 0;
287
7.41k
  int result                             = 0;
288
289
7.41k
  if( descriptor_file == NULL )
290
0
  {
291
0
    libcerror_error_set(
292
0
     error,
293
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
294
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
295
0
     "%s: invalid descriptor file.",
296
0
     function );
297
298
0
    return( -1 );
299
0
  }
300
7.41k
  if( libcsplit_narrow_string_split(
301
7.41k
       value_string,
302
7.41k
       value_string_size,
303
7.41k
       '\n',
304
7.41k
       &lines,
305
7.41k
       error ) != 1 )
306
0
  {
307
0
    libcerror_error_set(
308
0
     error,
309
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
310
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
311
0
     "%s: unable to split file data into lines.",
312
0
     function );
313
314
0
    goto on_error;
315
0
  }
316
7.41k
  if( libcsplit_narrow_split_string_get_number_of_segments(
317
7.41k
       lines,
318
7.41k
       &number_of_lines,
319
7.41k
       error ) != 1 )
320
1
  {
321
1
    libcerror_error_set(
322
1
     error,
323
1
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
324
1
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
325
1
     "%s: unable to retrieve number of lines.",
326
1
     function );
327
328
1
    goto on_error;
329
1
  }
330
7.41k
  if( libvmdk_descriptor_file_read_signature(
331
7.41k
       lines,
332
7.41k
       number_of_lines,
333
7.41k
       &line_index,
334
7.41k
       error ) != 1 )
335
46
  {
336
46
    libcerror_error_set(
337
46
     error,
338
46
     LIBCERROR_ERROR_DOMAIN_IO,
339
46
     LIBCERROR_IO_ERROR_READ_FAILED,
340
46
     "%s: unable to read descriptor file signature.",
341
46
     function );
342
343
46
    goto on_error;
344
46
  }
345
7.36k
  if( libvmdk_descriptor_file_read_header(
346
7.36k
       descriptor_file,
347
7.36k
       lines,
348
7.36k
       number_of_lines,
349
7.36k
       &line_index,
350
7.36k
       error ) != 1 )
351
947
  {
352
947
    libcerror_error_set(
353
947
     error,
354
947
     LIBCERROR_ERROR_DOMAIN_IO,
355
947
     LIBCERROR_IO_ERROR_READ_FAILED,
356
947
     "%s: unable to read descriptor file header.",
357
947
     function );
358
359
947
    goto on_error;
360
947
  }
361
6.41k
  if( libvmdk_descriptor_file_read_extents(
362
6.41k
       descriptor_file,
363
6.41k
       lines,
364
6.41k
       number_of_lines,
365
6.41k
       &line_index,
366
6.41k
       extents_values_array,
367
6.41k
       error ) != 1 )
368
4.61k
  {
369
4.61k
    libcerror_error_set(
370
4.61k
     error,
371
4.61k
     LIBCERROR_ERROR_DOMAIN_IO,
372
4.61k
     LIBCERROR_IO_ERROR_READ_FAILED,
373
4.61k
     "%s: unable to read extents.",
374
4.61k
     function );
375
376
4.61k
    goto on_error;
377
4.61k
  }
378
1.80k
  result = libvmdk_descriptor_file_read_change_tracking_file(
379
1.80k
            descriptor_file,
380
1.80k
            lines,
381
1.80k
            number_of_lines,
382
1.80k
            &line_index,
383
1.80k
            error );
384
385
1.80k
  if( result == -1 )
386
342
  {
387
342
    libcerror_error_set(
388
342
     error,
389
342
     LIBCERROR_ERROR_DOMAIN_IO,
390
342
     LIBCERROR_IO_ERROR_READ_FAILED,
391
342
     "%s: unable to read change tracking file.",
392
342
     function );
393
394
342
    goto on_error;
395
342
  }
396
1.46k
  if( libvmdk_descriptor_file_read_disk_database(
397
1.46k
       descriptor_file,
398
1.46k
       lines,
399
1.46k
       number_of_lines,
400
1.46k
       &line_index,
401
1.46k
       error ) != 1 )
402
606
  {
403
606
    libcerror_error_set(
404
606
     error,
405
606
     LIBCERROR_ERROR_DOMAIN_IO,
406
606
     LIBCERROR_IO_ERROR_READ_FAILED,
407
606
     "%s: unable to read disk database.",
408
606
     function );
409
410
606
    goto on_error;
411
606
  }
412
859
  if( libcsplit_narrow_split_string_free(
413
859
       &lines,
414
859
       error ) != 1 )
415
0
  {
416
0
    libcerror_error_set(
417
0
     error,
418
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
419
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
420
0
     "%s: unable to free lines.",
421
0
     function );
422
423
0
    goto on_error;
424
0
  }
425
859
  return( 1 );
426
427
6.55k
on_error:
428
6.55k
  if( lines != NULL )
429
6.55k
  {
430
6.55k
    libcsplit_narrow_split_string_free(
431
6.55k
     &lines,
432
6.55k
     NULL );
433
6.55k
  }
434
6.55k
  return( -1 );
435
859
}
436
437
/* Reads the signature from the descriptor file
438
 * Returns the 1 if successful, 0 if no signature was found or -1 on error
439
 */
440
int libvmdk_descriptor_file_read_signature(
441
     libcsplit_narrow_split_string_t *lines,
442
     int number_of_lines,
443
     int *line_index,
444
     libcerror_error_t **error )
445
15.0k
{
446
15.0k
  static char *function            = "libvmdk_descriptor_file_read_signature";
447
15.0k
  char *line_string_segment        = NULL;
448
15.0k
  size_t line_string_segment_index = 0;
449
15.0k
  size_t line_string_segment_size  = 0;
450
15.0k
  int result                       = 0;
451
15.0k
  int safe_line_index              = 0;
452
453
15.0k
  if( line_index == NULL )
454
0
  {
455
0
    libcerror_error_set(
456
0
     error,
457
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
458
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
459
0
     "%s: invalid line index.",
460
0
     function );
461
462
0
    return( -1 );
463
0
  }
464
15.0k
  if( number_of_lines <= 0 )
465
0
  {
466
0
    libcerror_error_set(
467
0
     error,
468
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
469
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
470
0
     "%s: invalid number of lines value out of bounds.",
471
0
     function );
472
473
0
    return( -1 );
474
0
  }
475
85.2k
  while( safe_line_index < number_of_lines )
476
85.0k
  {
477
85.0k
    if( libcsplit_narrow_split_string_get_segment_by_index(
478
85.0k
         lines,
479
85.0k
         safe_line_index,
480
85.0k
         &line_string_segment,
481
85.0k
         &line_string_segment_size,
482
85.0k
         error ) != 1 )
483
0
    {
484
0
      libcerror_error_set(
485
0
       error,
486
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
487
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
488
0
       "%s: unable to retrieve line: %d.",
489
0
       function,
490
0
       safe_line_index );
491
492
0
      return( -1 );
493
0
    }
494
85.0k
    if( line_string_segment == NULL )
495
0
    {
496
0
      libcerror_error_set(
497
0
       error,
498
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
499
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
500
0
       "%s: missing line string segment: %d.",
501
0
       function,
502
0
       safe_line_index );
503
504
0
      return( -1 );
505
0
    }
506
85.0k
    if( line_string_segment_size < 2 )
507
68.5k
    {
508
68.5k
      safe_line_index++;
509
510
68.5k
      continue;
511
68.5k
    }
512
    /* Ignore trailing white space
513
     */
514
16.5k
    line_string_segment_index = line_string_segment_size - 2;
515
516
130k
    while( line_string_segment_index > 0 )
517
129k
    {
518
129k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
519
104k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
520
102k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
521
101k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
522
100k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
523
15.9k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
524
15.6k
      {
525
15.6k
        break;
526
15.6k
      }
527
113k
      line_string_segment_index--;
528
113k
      line_string_segment_size--;
529
113k
    }
530
    /* Ignore leading white space
531
     */
532
16.5k
    line_string_segment_index = 0;
533
534
18.0k
    while( line_string_segment_index < line_string_segment_size )
535
17.6k
    {
536
17.6k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
537
17.3k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
538
17.3k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
539
16.7k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
540
16.5k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
541
16.2k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
542
16.1k
      {
543
16.1k
        break;
544
16.1k
      }
545
1.50k
      line_string_segment_index++;
546
1.50k
      line_string_segment_size--;
547
1.50k
    }
548
    /* Only allow comment or empty lines
549
     */
550
16.5k
    if( line_string_segment_size > 1 )
551
16.1k
    {
552
16.1k
      if( line_string_segment[ line_string_segment_index ] == '#' )
553
16.0k
      {
554
16.0k
        if( ( line_string_segment_size == 22 )
555
15.1k
         && ( narrow_string_compare_no_case(
556
15.1k
               &( line_string_segment[ line_string_segment_index ] ),
557
15.1k
               vmdk_descriptor_file_signature,
558
15.1k
               21 ) == 0 ) )
559
14.7k
        {
560
14.7k
          result = 1;
561
562
14.7k
          break;
563
14.7k
        }
564
16.0k
      }
565
124
      else if( line_string_segment[ line_string_segment_index ] != 0 )
566
118
      {
567
118
        break;
568
118
      }
569
16.1k
    }
570
1.68k
    safe_line_index++;
571
1.68k
  }
572
15.0k
  *line_index = safe_line_index;
573
574
15.0k
  return( result );
575
15.0k
}
576
577
/* Reads the header from the descriptor file
578
 * Returns the 1 if successful or -1 on error
579
 */
580
int libvmdk_descriptor_file_read_header(
581
     libvmdk_descriptor_file_t *descriptor_file,
582
     libcsplit_narrow_split_string_t *lines,
583
     int number_of_lines,
584
     int *line_index,
585
     libcerror_error_t **error )
586
7.36k
{
587
7.36k
  char *line_string_segment        = NULL;
588
7.36k
  char *value                      = NULL;
589
7.36k
  char *value_identifier           = NULL;
590
7.36k
  static char *function            = "libvmdk_descriptor_file_read_header";
591
7.36k
  size_t line_string_segment_index = 0;
592
7.36k
  size_t line_string_segment_size  = 0;
593
7.36k
  size_t value_identifier_length   = 0;
594
7.36k
  size_t value_length              = 0;
595
7.36k
  uint64_t value_64bit             = 0;
596
7.36k
  int safe_line_index              = 0;
597
598
7.36k
  if( descriptor_file == NULL )
599
0
  {
600
0
    libcerror_error_set(
601
0
     error,
602
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
603
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
604
0
     "%s: invalid descriptor file.",
605
0
     function );
606
607
0
    return( -1 );
608
0
  }
609
7.36k
  if( line_index == NULL )
610
0
  {
611
0
    libcerror_error_set(
612
0
     error,
613
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
614
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
615
0
     "%s: invalid line index.",
616
0
     function );
617
618
0
    return( -1 );
619
0
  }
620
7.36k
  if( number_of_lines <= 0 )
621
0
  {
622
0
    libcerror_error_set(
623
0
     error,
624
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
625
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
626
0
     "%s: invalid number of lines value out of bounds.",
627
0
     function );
628
629
0
    return( -1 );
630
0
  }
631
7.36k
  safe_line_index = *line_index;
632
633
7.36k
  if( ( safe_line_index < 0 )
634
7.36k
   || ( safe_line_index >= number_of_lines ) )
635
0
  {
636
0
    libcerror_error_set(
637
0
     error,
638
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
639
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
640
0
     "%s: invalid line index value out of bounds.",
641
0
     function );
642
643
0
    return( -1 );
644
0
  }
645
7.19M
  while( safe_line_index < number_of_lines )
646
7.18M
  {
647
7.18M
    if( libcsplit_narrow_split_string_get_segment_by_index(
648
7.18M
         lines,
649
7.18M
         safe_line_index,
650
7.18M
         &line_string_segment,
651
7.18M
         &line_string_segment_size,
652
7.18M
         error ) != 1 )
653
0
    {
654
0
      libcerror_error_set(
655
0
       error,
656
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
657
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
658
0
       "%s: unable to retrieve line: %d.",
659
0
       function,
660
0
       safe_line_index );
661
662
0
      goto on_error;
663
0
    }
664
7.18M
    if( line_string_segment == NULL )
665
0
    {
666
0
      libcerror_error_set(
667
0
       error,
668
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
669
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
670
0
       "%s: missing line string segment: %d.",
671
0
       function,
672
0
       safe_line_index );
673
674
0
      goto on_error;
675
0
    }
676
7.18M
    if( line_string_segment_size < 2 )
677
7.13M
    {
678
7.13M
      safe_line_index++;
679
680
7.13M
      continue;
681
7.13M
    }
682
    /* Ignore trailing white space
683
     */
684
50.5k
    line_string_segment_index = line_string_segment_size - 2;
685
686
123k
    while( line_string_segment_index > 0 )
687
109k
    {
688
109k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
689
104k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
690
103k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
691
102k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
692
101k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
693
36.3k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
694
36.0k
      {
695
36.0k
        break;
696
36.0k
      }
697
73.4k
      line_string_segment_index--;
698
73.4k
      line_string_segment_size--;
699
73.4k
    }
700
    /* Ignore leading white space
701
     */
702
50.5k
    line_string_segment_index = 0;
703
704
5.02M
    while( line_string_segment_index < line_string_segment_size )
705
5.02M
    {
706
5.02M
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
707
4.55M
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
708
4.55M
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
709
4.53M
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
710
4.53M
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
711
52.6k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
712
50.2k
      {
713
50.2k
        break;
714
50.2k
      }
715
4.97M
      line_string_segment_index++;
716
4.97M
    }
717
    /* Skip an empty line
718
     */
719
50.5k
    if( ( line_string_segment_index >= line_string_segment_size )
720
50.2k
     || ( line_string_segment[ line_string_segment_index ] == 0 ) )
721
1.05k
    {
722
1.05k
      safe_line_index++;
723
724
1.05k
      continue;
725
1.05k
    }
726
49.4k
    if( ( line_string_segment_size - line_string_segment_index ) == 21 )
727
4.17k
    {
728
      /* Check for the end of the header
729
       */
730
4.17k
      if( narrow_string_compare_no_case(
731
4.17k
           &( line_string_segment[ line_string_segment_index ] ),
732
4.17k
           vmdk_descriptor_file_extent_section_signature,
733
4.17k
           20 ) == 0 )
734
2.68k
      {
735
2.68k
        break;
736
2.68k
      }
737
4.17k
    }
738
    /* Determine the value identifier
739
     */
740
46.7k
    value_identifier        = &( line_string_segment[ line_string_segment_index ] );
741
46.7k
    value_identifier_length = 0;
742
743
5.30M
    while( line_string_segment_index < line_string_segment_size )
744
5.28M
    {
745
5.28M
      if( ( line_string_segment[ line_string_segment_index ] == '\t' )
746
5.28M
       || ( line_string_segment[ line_string_segment_index ] == '\n' )
747
5.28M
       || ( line_string_segment[ line_string_segment_index ] == '\f' )
748
5.28M
       || ( line_string_segment[ line_string_segment_index ] == '\v' )
749
5.28M
       || ( line_string_segment[ line_string_segment_index ] == '\r' )
750
5.27M
       || ( line_string_segment[ line_string_segment_index ] == ' ' )
751
5.27M
       || ( line_string_segment[ line_string_segment_index ] == '=' ) )
752
28.2k
      {
753
28.2k
        break;
754
28.2k
      }
755
5.25M
      value_identifier_length++;
756
757
5.25M
      line_string_segment_index++;
758
5.25M
    }
759
    /* Skip a line not containing a value
760
     */
761
46.7k
    if( ( line_string_segment_index >= line_string_segment_size )
762
28.2k
     || ( line_string_segment[ line_string_segment_index ] == 0 ) )
763
18.5k
    {
764
18.5k
      safe_line_index++;
765
766
18.5k
      continue;
767
18.5k
    }
768
    /* Make sure the value identifier is terminated by an end of string
769
     */
770
28.2k
    line_string_segment[ line_string_segment_index ] = 0;
771
772
28.2k
    line_string_segment_index++;
773
774
    /* Ignore whitespace
775
     */
776
396k
    while( line_string_segment_index < line_string_segment_size )
777
395k
    {
778
395k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
779
376k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
780
376k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
781
374k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
782
374k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
783
28.0k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
784
27.6k
      {
785
27.6k
        break;
786
27.6k
      }
787
367k
      line_string_segment_index++;
788
367k
    }
789
28.2k
    if( line_string_segment[ line_string_segment_index ] == '=' )
790
479
    {
791
479
      line_string_segment_index++;
792
793
5.13k
      while( line_string_segment_index < line_string_segment_size )
794
4.92k
      {
795
4.92k
        if( ( line_string_segment[ line_string_segment_index ] != '\t' )
796
4.36k
         && ( line_string_segment[ line_string_segment_index ] != '\n' )
797
4.09k
         && ( line_string_segment[ line_string_segment_index ] != '\f' )
798
3.87k
         && ( line_string_segment[ line_string_segment_index ] != '\v' )
799
3.67k
         && ( line_string_segment[ line_string_segment_index ] != '\r' )
800
448
         && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
801
273
        {
802
273
          break;
803
273
        }
804
4.65k
        line_string_segment_index++;
805
4.65k
      }
806
479
    }
807
    /* Skip a line not containing a value
808
     */
809
28.2k
    if( ( line_string_segment_index >= line_string_segment_size )
810
27.3k
     || ( line_string_segment[ line_string_segment_index ] == 0 ) )
811
1.50k
    {
812
1.50k
      safe_line_index++;
813
814
1.50k
      continue;
815
1.50k
    }
816
    /* Determine the value
817
     */
818
26.7k
    value        = &( line_string_segment[ line_string_segment_index ] );
819
26.7k
    value_length = line_string_segment_size - 1;
820
821
    /* Ingore quotes at the beginning of the value data
822
     */
823
26.7k
    if( ( line_string_segment[ line_string_segment_index ] == '"' )
824
26.0k
     || ( line_string_segment[ line_string_segment_index ] == '\'' ) )
825
1.09k
    {
826
1.09k
      line_string_segment_index++;
827
1.09k
      value++;
828
1.09k
      value_length--;
829
1.09k
    }
830
    /* Ingore quotes at the end of the value data
831
     */
832
26.7k
    if( ( line_string_segment[ value_length - 1 ] == '"' )
833
26.4k
     || ( line_string_segment[ value_length - 1 ] == '\'' ) )
834
516
    {
835
516
      value_length--;
836
516
    }
837
    /* Make sure the value is terminated by an end of string
838
     */
839
26.7k
    line_string_segment[ value_length ] = 0;
840
841
26.7k
    value_length -= line_string_segment_index;
842
843
26.7k
    if( value_identifier_length == 3 )
844
698
    {
845
698
      if( narrow_string_compare_no_case(
846
698
           value_identifier,
847
698
           "CID",
848
698
           3 ) == 0 )
849
439
      {
850
#if defined( HAVE_DEBUG_OUTPUT )
851
        if( libcnotify_verbose != 0 )
852
        {
853
          libcnotify_printf(
854
           "%s: content identifier\t\t\t: %s\n",
855
           function,
856
           value );
857
        }
858
#endif
859
439
        if( libfvalue_utf8_string_copy_to_integer(
860
439
             (uint8_t *) value,
861
439
             value_length,
862
439
             &value_64bit,
863
439
             64,
864
439
             LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL | LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR,
865
439
             error ) != 1 )
866
42
        {
867
42
          libcerror_error_set(
868
42
           error,
869
42
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
870
42
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
871
42
           "%s: unable to determine content identifier value from string.",
872
42
           function );
873
874
42
          goto on_error;
875
42
        }
876
397
        if( value_64bit > (uint64_t) UINT32_MAX )
877
67
        {
878
67
          libcerror_error_set(
879
67
           error,
880
67
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
881
67
           LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
882
67
           "%s: invalid content identifier value exceeds maximum.",
883
67
           function );
884
885
67
          goto on_error;
886
67
        }
887
330
        descriptor_file->content_identifier = (uint32_t) value_64bit;
888
330
      }
889
698
    }
890
26.0k
    else if( value_identifier_length == 7 )
891
615
    {
892
615
      if( narrow_string_compare_no_case(
893
615
           value_identifier,
894
615
           "version",
895
615
           7 ) == 0 )
896
351
      {
897
#if defined( HAVE_DEBUG_OUTPUT )
898
        if( libcnotify_verbose != 0 )
899
        {
900
          libcnotify_printf(
901
           "%s: version\t\t\t\t: %s\n",
902
           function,
903
           value );
904
        }
905
#endif
906
351
        if( libfvalue_utf8_string_copy_to_integer(
907
351
             (uint8_t *) value,
908
351
             value_length,
909
351
             &value_64bit,
910
351
             64,
911
351
             LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL_UNSIGNED,
912
351
             error ) != 1 )
913
28
        {
914
28
          libcerror_error_set(
915
28
           error,
916
28
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
917
28
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
918
28
           "%s: unable to determine version value from string.",
919
28
           function );
920
921
28
          goto on_error;
922
28
        }
923
323
        if( value_64bit > (uint64_t) INT_MAX )
924
66
        {
925
66
          libcerror_error_set(
926
66
           error,
927
66
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
928
66
           LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
929
66
           "%s: invalid version value exceeds maximum.",
930
66
           function );
931
932
66
          goto on_error;
933
66
        }
934
257
        descriptor_file->version = (int) value_64bit;
935
257
      }
936
615
    }
937
25.4k
    else if( value_identifier_length == 8 )
938
4.90k
    {
939
4.90k
      if( narrow_string_compare_no_case(
940
4.90k
           value_identifier,
941
4.90k
           "encoding",
942
4.90k
           8 ) == 0 )
943
4.64k
      {
944
#if defined( HAVE_DEBUG_OUTPUT )
945
        if( libcnotify_verbose != 0 )
946
        {
947
          libcnotify_printf(
948
           "%s: encoding\t\t\t\t: %s\n",
949
           function,
950
           value );
951
        }
952
#endif
953
4.64k
        if( ( value_length == 3 )
954
232
         && ( value[ 0 ] == 'G' )
955
222
         && ( value[ 1 ] == 'B' )
956
213
         && ( value[ 2 ] == 'K' ) )
957
203
        {
958
203
          descriptor_file->encoding = LIBUNA_CODEPAGE_WINDOWS_936;
959
203
        }
960
4.44k
        else if( ( value_length == 4 )
961
262
              && ( value[ 0 ] == 'B' )
962
250
              && ( value[ 1 ] == 'i' )
963
241
              && ( value[ 2 ] == 'g' )
964
233
              && ( value[ 3 ] == '5' ) )
965
222
        {
966
222
          descriptor_file->encoding = LIBUNA_CODEPAGE_WINDOWS_950;
967
222
        }
968
4.21k
        else if( ( value_length == 5 )
969
2.25k
              && ( value[ 0 ] == 'U' )
970
233
              && ( value[ 1 ] == 'T' )
971
223
              && ( value[ 2 ] == 'F' )
972
213
              && ( value[ 3 ] == '-' )
973
203
              && ( value[ 4 ] == '8' ) )
974
194
        {
975
194
          descriptor_file->encoding = 0;
976
194
        }
977
4.02k
        else if( ( value_length == 9 )
978
272
              && ( value[ 0 ] == 'S' )
979
261
              && ( value[ 1 ] == 'h' )
980
259
              && ( value[ 2 ] == 'i' )
981
250
              && ( value[ 3 ] == 'f' )
982
240
              && ( value[ 4 ] == 't' )
983
230
              && ( value[ 5 ] == '_' )
984
221
              && ( value[ 6 ] == 'J' )
985
213
              && ( value[ 7 ] == 'I' )
986
203
              && ( value[ 8 ] == 'S' ) )
987
194
        {
988
194
          descriptor_file->encoding = LIBUNA_CODEPAGE_WINDOWS_932;
989
194
        }
990
3.83k
        else if( libclocale_codepage_copy_from_string(
991
3.83k
                  &( descriptor_file->encoding ),
992
3.83k
                  value,
993
3.83k
                  value_length,
994
3.83k
                  LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS,
995
3.83k
                  error ) != 1 )
996
684
        {
997
684
          libcerror_error_set(
998
684
           error,
999
684
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1000
684
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1001
684
           "%s: unable to determine codepage value from string.",
1002
684
           function );
1003
1004
684
          goto on_error;
1005
684
        }
1006
4.64k
      }
1007
4.90k
    }
1008
20.4k
    else if( value_identifier_length == 9 )
1009
591
    {
1010
591
      if( narrow_string_compare_no_case(
1011
591
           value_identifier,
1012
591
           "parentCID",
1013
591
           9 ) == 0 )
1014
313
      {
1015
#if defined( HAVE_DEBUG_OUTPUT )
1016
        if( libcnotify_verbose != 0 )
1017
        {
1018
          libcnotify_printf(
1019
           "%s: parent content identifier\t\t: %s\n",
1020
           function,
1021
           value );
1022
        }
1023
#endif
1024
313
        if( libfvalue_utf8_string_copy_to_integer(
1025
313
             (uint8_t *) value,
1026
313
             value_length,
1027
313
             &value_64bit,
1028
313
             64,
1029
313
             LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL | LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR,
1030
313
             error ) != 1 )
1031
1
        {
1032
1
          libcerror_error_set(
1033
1
           error,
1034
1
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1035
1
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1036
1
           "%s: unable to determine parent content identifier value from string.",
1037
1
           function );
1038
1039
1
          goto on_error;
1040
1
        }
1041
312
        if( value_64bit > (uint64_t) UINT32_MAX )
1042
58
        {
1043
58
          libcerror_error_set(
1044
58
           error,
1045
58
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1046
58
           LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1047
58
           "%s: invalid content parent identifier value exceeds maximum.",
1048
58
           function );
1049
1050
58
          goto on_error;
1051
58
        }
1052
254
        descriptor_file->parent_content_identifier     = (uint32_t) value_64bit;
1053
254
        descriptor_file->parent_content_identifier_set = 1;
1054
254
      }
1055
591
    }
1056
19.9k
    else if( value_identifier_length == 10 )
1057
9.09k
    {
1058
9.09k
      if( narrow_string_compare_no_case(
1059
9.09k
           value_identifier,
1060
9.09k
           "createType",
1061
9.09k
           10 ) == 0 )
1062
8.70k
      {
1063
#if defined( HAVE_DEBUG_OUTPUT )
1064
        if( libcnotify_verbose != 0 )
1065
        {
1066
          libcnotify_printf(
1067
           "%s: disk type\t\t\t\t: %s\n",
1068
           function,
1069
           value );
1070
        }
1071
#endif
1072
8.70k
        if( value_length == 4 )
1073
421
        {
1074
421
          if( narrow_string_compare_no_case(
1075
421
               value,
1076
421
               "vmfs",
1077
421
               4 ) == 0 )
1078
194
          {
1079
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_VMFS_FLAT;
1080
194
          }
1081
421
        }
1082
8.28k
        else if( value_length == 6 )
1083
440
        {
1084
440
          if( narrow_string_compare_no_case(
1085
440
               value,
1086
440
               "custom",
1087
440
               6 ) == 0 )
1088
194
          {
1089
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_CUSTOM;
1090
194
          }
1091
440
        }
1092
7.84k
        else if( value_length == 7 )
1093
654
        {
1094
654
          if( narrow_string_compare_no_case(
1095
654
               value,
1096
654
               "vmfsRaw",
1097
654
               7 ) == 0 )
1098
194
          {
1099
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_VMFS_RAW;
1100
194
          }
1101
460
          else if( narrow_string_compare_no_case(
1102
460
                    value,
1103
460
                    "vmfsRDM",
1104
460
                    7 ) == 0 )
1105
194
          {
1106
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_VMFS_RDM;
1107
194
          }
1108
654
        }
1109
7.18k
        else if( value_length == 8 )
1110
669
        {
1111
669
          if( narrow_string_compare_no_case(
1112
669
               value,
1113
669
               "vmfsRDMP",
1114
669
               8 ) == 0 )
1115
196
          {
1116
196
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_VMFS_RDMP;
1117
196
          }
1118
473
          else if( narrow_string_compare_no_case(
1119
473
                    value,
1120
473
                    "vmfsThin",
1121
473
                    8 ) == 0 )
1122
194
          {
1123
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_VMFS_SPARSE_THIN;
1124
194
          }
1125
669
        }
1126
6.51k
        else if( value_length == 10 )
1127
795
        {
1128
795
          if( narrow_string_compare_no_case(
1129
795
               value,
1130
795
               "fullDevice",
1131
795
               10 ) == 0 )
1132
194
          {
1133
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_DEVICE;
1134
194
          }
1135
601
          else if( narrow_string_compare_no_case(
1136
601
                    value,
1137
601
                    "vmfsSparse",
1138
601
                    10 ) == 0 )
1139
239
          {
1140
239
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_VMFS_SPARSE;
1141
239
          }
1142
795
        }
1143
5.72k
        else if( value_length == 14 )
1144
496
        {
1145
496
          if( narrow_string_compare_no_case(
1146
496
               value,
1147
496
               "monolithicFlat",
1148
496
               14 ) == 0 )
1149
194
          {
1150
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_MONOLITHIC_FLAT;
1151
194
          }
1152
496
        }
1153
5.22k
        else if( value_length == 15 )
1154
569
        {
1155
569
          if( narrow_string_compare_no_case(
1156
569
               value,
1157
569
               "streamOptimized",
1158
569
               15 ) == 0 )
1159
236
          {
1160
236
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_STREAM_OPTIMIZED;
1161
236
          }
1162
569
        }
1163
4.65k
        else if( value_length == 16 )
1164
1.49k
        {
1165
1.49k
          if( narrow_string_compare_no_case(
1166
1.49k
               value,
1167
1.49k
               "2GbMaxExtentFlat",
1168
1.49k
               16 ) == 0 )
1169
194
          {
1170
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_FLAT_2GB_EXTENT;
1171
194
          }
1172
1.29k
          else if( narrow_string_compare_no_case(
1173
1.29k
                    value,
1174
1.29k
                    "monolithicSparse",
1175
1.29k
                    16 ) == 0 )
1176
208
          {
1177
208
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_MONOLITHIC_SPARSE;
1178
208
          }
1179
1.08k
          else if( narrow_string_compare_no_case(
1180
1.08k
                    value,
1181
1.08k
                    "vmfsPreallocated",
1182
1.08k
                    16 ) == 0 )
1183
194
          {
1184
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_VMFS_FLAT_PRE_ALLOCATED;
1185
194
          }
1186
895
          else if( narrow_string_compare_no_case(
1187
895
                    value,
1188
895
                    "vmfsRawDeviceMap",
1189
895
                    16 ) == 0 )
1190
194
          {
1191
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_VMFS_RDM;
1192
194
          }
1193
1.49k
        }
1194
3.16k
        else if( value_length == 17 )
1195
530
        {
1196
530
          if( narrow_string_compare_no_case(
1197
530
               value,
1198
530
               "partitionedDevice",
1199
530
               17 ) == 0 )
1200
194
          {
1201
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_DEVICE_PARITIONED;
1202
194
          }
1203
530
        }
1204
2.63k
        else if( value_length == 18 )
1205
883
        {
1206
883
          if( narrow_string_compare_no_case(
1207
883
               value,
1208
883
               "2GbMaxExtentSparse",
1209
883
               18 ) == 0 )
1210
195
          {
1211
195
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_SPARSE_2GB_EXTENT;
1212
195
          }
1213
688
          else if( narrow_string_compare_no_case(
1214
688
                    value,
1215
688
                    "twoGbMaxExtentFlat",
1216
688
                    18 ) == 0 )
1217
194
          {
1218
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_FLAT_2GB_EXTENT;
1219
194
          }
1220
883
        }
1221
1.75k
        else if( value_length == 20 )
1222
872
        {
1223
872
          if( narrow_string_compare_no_case(
1224
872
               value,
1225
872
               "twoGbMaxExtentSparse",
1226
872
               20 ) == 0 )
1227
199
          {
1228
199
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_SPARSE_2GB_EXTENT;
1229
199
          }
1230
673
          else if( narrow_string_compare_no_case(
1231
673
                    value,
1232
673
                    "vmfsEagerZeroedThick",
1233
673
                    20 ) == 0 )
1234
194
          {
1235
194
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_VMFS_FLAT_ZEROED;
1236
194
          }
1237
872
        }
1238
882
        else if( value_length == 27 )
1239
521
        {
1240
521
          if( narrow_string_compare_no_case(
1241
521
               value,
1242
521
               "vmfsPassthroughRawDeviceMap",
1243
521
               27 ) == 0 )
1244
206
          {
1245
206
            descriptor_file->disk_type = LIBVMDK_DISK_TYPE_VMFS_RDMP;
1246
206
          }
1247
521
        }
1248
8.70k
      }
1249
9.09k
    }
1250
10.8k
    else if( value_identifier_length == 18 )
1251
1.08k
    {
1252
1.08k
      if( narrow_string_compare_no_case(
1253
1.08k
           value_identifier,
1254
1.08k
           "parentFileNameHint",
1255
1.08k
           18 ) == 0 )
1256
747
      {
1257
747
        if( descriptor_file->parent_filename != NULL )
1258
417
        {
1259
417
          memory_free(
1260
417
           descriptor_file->parent_filename );
1261
1262
417
          descriptor_file->parent_filename      = NULL;
1263
417
          descriptor_file->parent_filename_size = 0;
1264
417
        }
1265
747
        if( value_length > (size_t) ( MEMORY_MAXIMUM_ALLOCATION_SIZE - 1 ) )
1266
1
        {
1267
1
          libcerror_error_set(
1268
1
           error,
1269
1
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1270
1
           LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1271
1
           "%s: invalid parent filename length exceeds maximum allocation size.",
1272
1
           function );
1273
1274
1
          goto on_error;
1275
1
        }
1276
746
        descriptor_file->parent_filename = (uint8_t *) memory_allocate(
1277
746
                                                        sizeof( uint8_t ) * ( value_length + 1 ) );
1278
1279
746
        if( descriptor_file->parent_filename == NULL )
1280
0
        {
1281
0
          libcerror_error_set(
1282
0
           error,
1283
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
1284
0
           LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1285
0
           "%s: unable to create parent filename.",
1286
0
           function );
1287
1288
0
          goto on_error;
1289
0
        }
1290
746
        if( memory_copy(
1291
746
             descriptor_file->parent_filename,
1292
746
             value,
1293
746
             value_length ) == NULL )
1294
0
        {
1295
0
          libcerror_error_set(
1296
0
           error,
1297
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
1298
0
           LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1299
0
           "%s: unable to copy parent filename.",
1300
0
           function );
1301
1302
0
          goto on_error;
1303
0
        }
1304
746
        descriptor_file->parent_filename[ value_length ] = 0;
1305
1306
746
        descriptor_file->parent_filename_size = value_length + 1;
1307
1308
#if defined( HAVE_DEBUG_OUTPUT )
1309
        if( libcnotify_verbose != 0 )
1310
        {
1311
          libcnotify_printf(
1312
           "%s: parent filename\t\t\t: %s\n",
1313
           function,
1314
           descriptor_file->parent_filename );
1315
        }
1316
#endif
1317
746
      }
1318
1.08k
    }
1319
#if defined( HAVE_DEBUG_OUTPUT )
1320
    else if( libcnotify_verbose != 0 )
1321
    {
1322
      libcnotify_printf(
1323
       "%s: value: %d\t\t\t\t: %s = %s\n",
1324
       function,
1325
       safe_line_index,
1326
       value_identifier,
1327
       value );
1328
    }
1329
#endif
1330
25.7k
    safe_line_index++;
1331
25.7k
  }
1332
#if defined( HAVE_DEBUG_OUTPUT )
1333
  if( libcnotify_verbose != 0 )
1334
  {
1335
    libcnotify_printf(
1336
     "\n" );
1337
  }
1338
#endif
1339
6.41k
  *line_index = safe_line_index;
1340
1341
6.41k
  return( 1 );
1342
1343
947
on_error:
1344
947
  if( descriptor_file->parent_filename != NULL )
1345
1
  {
1346
1
    memory_free(
1347
1
     descriptor_file->parent_filename );
1348
1349
1
    descriptor_file->parent_filename = NULL;
1350
1
  }
1351
947
  descriptor_file->parent_filename_size = 0;
1352
1353
947
  return( -1 );
1354
7.36k
}
1355
1356
/* Reads the extents from the descriptor file
1357
 * Returns the 1 if successful or -1 on error
1358
 */
1359
int libvmdk_descriptor_file_read_extents(
1360
     libvmdk_descriptor_file_t *descriptor_file,
1361
     libcsplit_narrow_split_string_t *lines,
1362
     int number_of_lines,
1363
     int *line_index,
1364
     libcdata_array_t *extents_values_array,
1365
     libcerror_error_t **error )
1366
6.41k
{
1367
6.41k
  libvmdk_extent_values_t *extent_values = NULL;
1368
6.41k
  static char *function                  = "libvmdk_descriptor_file_read_extents";
1369
6.41k
  char *line_string_segment              = NULL;
1370
6.41k
  size_t line_string_segment_index       = 0;
1371
6.41k
  size_t line_string_segment_size        = 0;
1372
6.41k
  int entry_index                        = 0;
1373
6.41k
  int safe_line_index                    = 0;
1374
1375
6.41k
  if( descriptor_file == NULL )
1376
0
  {
1377
0
    libcerror_error_set(
1378
0
     error,
1379
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1380
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1381
0
     "%s: invalid descriptor file.",
1382
0
     function );
1383
1384
0
    return( -1 );
1385
0
  }
1386
6.41k
  if( line_index == NULL )
1387
0
  {
1388
0
    libcerror_error_set(
1389
0
     error,
1390
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1391
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1392
0
     "%s: invalid line index.",
1393
0
     function );
1394
1395
0
    return( -1 );
1396
0
  }
1397
6.41k
  if( number_of_lines <= 0 )
1398
0
  {
1399
0
    libcerror_error_set(
1400
0
     error,
1401
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1402
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1403
0
     "%s: invalid number of lines value out of bounds.",
1404
0
     function );
1405
1406
0
    return( -1 );
1407
0
  }
1408
6.41k
  safe_line_index = *line_index;
1409
1410
6.41k
  if( ( safe_line_index < 0 )
1411
6.41k
   || ( safe_line_index >= number_of_lines ) )
1412
3.73k
  {
1413
3.73k
    libcerror_error_set(
1414
3.73k
     error,
1415
3.73k
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1416
3.73k
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1417
3.73k
     "%s: invalid line index value out of bounds.",
1418
3.73k
     function );
1419
1420
3.73k
    return( -1 );
1421
3.73k
  }
1422
2.68k
  if( libcsplit_narrow_split_string_get_segment_by_index(
1423
2.68k
       lines,
1424
2.68k
       safe_line_index,
1425
2.68k
       &line_string_segment,
1426
2.68k
       &line_string_segment_size,
1427
2.68k
       error ) != 1 )
1428
0
  {
1429
0
    libcerror_error_set(
1430
0
     error,
1431
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1432
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1433
0
     "%s: unable to retrieve line: %d.",
1434
0
     function,
1435
0
     safe_line_index );
1436
1437
0
    goto on_error;
1438
0
  }
1439
2.68k
  if( line_string_segment == NULL )
1440
0
  {
1441
0
    libcerror_error_set(
1442
0
     error,
1443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1444
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1445
0
     "%s: missing line string segment: %d.",
1446
0
     function,
1447
0
     safe_line_index );
1448
1449
0
    goto on_error;
1450
0
  }
1451
2.68k
  if( line_string_segment_size < 2 )
1452
0
  {
1453
0
    libcerror_error_set(
1454
0
     error,
1455
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1456
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1457
0
     "%s: invalid line string segment: %d size value out of bounds.",
1458
0
     function,
1459
0
     safe_line_index );
1460
1461
0
    goto on_error;
1462
0
  }
1463
  /* Ignore trailing white space
1464
   */
1465
2.68k
  line_string_segment_index = line_string_segment_size - 2;
1466
1467
4.02k
  while( line_string_segment_index > 0 )
1468
4.02k
  {
1469
4.02k
    if( ( line_string_segment[ line_string_segment_index ] != '\t' )
1470
3.71k
     && ( line_string_segment[ line_string_segment_index ] != '\n' )
1471
3.71k
     && ( line_string_segment[ line_string_segment_index ] != '\f' )
1472
3.47k
     && ( line_string_segment[ line_string_segment_index ] != '\v' )
1473
3.27k
     && ( line_string_segment[ line_string_segment_index ] != '\r' )
1474
2.70k
     && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
1475
2.68k
    {
1476
2.68k
      break;
1477
2.68k
    }
1478
1.33k
    line_string_segment_index--;
1479
1.33k
    line_string_segment_size--;
1480
1.33k
  }
1481
  /* Ignore leading white space
1482
   */
1483
2.68k
  line_string_segment_index = 0;
1484
1485
3.12M
  while( line_string_segment_index < line_string_segment_size )
1486
3.12M
  {
1487
3.12M
    if( ( line_string_segment[ line_string_segment_index ] != '\t' )
1488
2.66M
     && ( line_string_segment[ line_string_segment_index ] != '\n' )
1489
2.66M
     && ( line_string_segment[ line_string_segment_index ] != '\f' )
1490
2.65M
     && ( line_string_segment[ line_string_segment_index ] != '\v' )
1491
2.64M
     && ( line_string_segment[ line_string_segment_index ] != '\r' )
1492
4.89k
     && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
1493
2.68k
    {
1494
2.68k
      break;
1495
2.68k
    }
1496
3.12M
    line_string_segment_index++;
1497
3.12M
  }
1498
2.68k
  if( ( ( line_string_segment_size - line_string_segment_index ) != 21 )
1499
2.68k
   || ( narrow_string_compare_no_case(
1500
2.68k
         &( line_string_segment[ line_string_segment_index ] ),
1501
2.68k
         vmdk_descriptor_file_extent_section_signature,
1502
2.68k
         20 ) != 0 ) )
1503
0
  {
1504
0
    libcerror_error_set(
1505
0
     error,
1506
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1507
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1508
0
     "%s: unsupported extent section signature.",
1509
0
     function );
1510
1511
0
    goto on_error;
1512
0
  }
1513
2.68k
  safe_line_index++;
1514
1515
2.68k
  if( libcdata_array_empty(
1516
2.68k
       extents_values_array,
1517
2.68k
       (int (*)(intptr_t **, libcerror_error_t **)) &libvmdk_extent_values_free,
1518
2.68k
       error ) != 1 )
1519
0
  {
1520
0
    libcerror_error_set(
1521
0
     error,
1522
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1523
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1524
0
     "%s: unable to empty extents values array.",
1525
0
     function );
1526
1527
0
    goto on_error;
1528
0
  }
1529
2.68k
  descriptor_file->media_size = 0;
1530
1531
300k
  while( safe_line_index < number_of_lines )
1532
300k
  {
1533
300k
    if( libcsplit_narrow_split_string_get_segment_by_index(
1534
300k
         lines,
1535
300k
         safe_line_index,
1536
300k
         &line_string_segment,
1537
300k
         &line_string_segment_size,
1538
300k
         error ) != 1 )
1539
0
    {
1540
0
      libcerror_error_set(
1541
0
       error,
1542
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1543
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1544
0
       "%s: unable to retrieve line: %d.",
1545
0
       function,
1546
0
       safe_line_index );
1547
1548
0
      goto on_error;
1549
0
    }
1550
300k
    if( line_string_segment == NULL )
1551
0
    {
1552
0
      libcerror_error_set(
1553
0
       error,
1554
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1555
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1556
0
       "%s: missing line string segment: %d.",
1557
0
       function,
1558
0
       safe_line_index );
1559
1560
0
      goto on_error;
1561
0
    }
1562
300k
    if( line_string_segment_size < 2 )
1563
12.3k
    {
1564
12.3k
      safe_line_index++;
1565
1566
12.3k
      continue;
1567
12.3k
    }
1568
    /* Ignore trailing white space
1569
     */
1570
287k
    line_string_segment_index = line_string_segment_size - 2;
1571
1572
347k
    while( line_string_segment_index > 0 )
1573
346k
    {
1574
346k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
1575
297k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
1576
297k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
1577
296k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
1578
295k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
1579
291k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
1580
287k
      {
1581
287k
        break;
1582
287k
      }
1583
59.5k
      line_string_segment_index--;
1584
59.5k
      line_string_segment_size--;
1585
59.5k
    }
1586
    /* Ignore leading white space
1587
     */
1588
287k
    line_string_segment_index = 0;
1589
1590
4.51M
    while( line_string_segment_index < line_string_segment_size )
1591
4.51M
    {
1592
4.51M
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
1593
4.22M
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
1594
4.22M
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
1595
4.20M
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
1596
4.19M
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
1597
293k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
1598
287k
      {
1599
287k
        break;
1600
287k
      }
1601
4.22M
      line_string_segment_index++;
1602
4.22M
    }
1603
    /* Skip an empty line
1604
     */
1605
287k
    if( ( line_string_segment_index >= line_string_segment_size )
1606
287k
     || ( line_string_segment[ line_string_segment_index ] == 0 ) )
1607
438
    {
1608
438
      safe_line_index++;
1609
1610
438
      continue;
1611
438
    }
1612
287k
    if( ( line_string_segment_size - line_string_segment_index ) == 21 )
1613
2.28k
    {
1614
      /* Check for the end of the section
1615
       */
1616
2.28k
      if( narrow_string_compare_no_case(
1617
2.28k
           &( line_string_segment[ line_string_segment_index ] ),
1618
2.28k
           vmdk_descriptor_file_disk_database_section_signature,
1619
2.28k
           20 ) == 0 )
1620
843
      {
1621
843
        break;
1622
843
      }
1623
2.28k
    }
1624
285k
    else if( ( line_string_segment_size - line_string_segment_index ) == 23 )
1625
8.81k
    {
1626
8.81k
      if( narrow_string_compare_no_case(
1627
8.81k
           &( line_string_segment[ line_string_segment_index ] ),
1628
8.81k
           vmdk_descriptor_file_change_tracking_file_signature,
1629
8.81k
           22 ) == 0 )
1630
622
      {
1631
622
        break;
1632
622
      }
1633
8.81k
    }
1634
    /* Make sure the string is terminated by an end of string
1635
     */
1636
285k
    line_string_segment[ line_string_segment_size - 1 ] = 0;
1637
1638
285k
    if( libvmdk_extent_values_initialize(
1639
285k
         &extent_values,
1640
285k
         error ) != 1 )
1641
0
    {
1642
0
      libcerror_error_set(
1643
0
       error,
1644
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1645
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1646
0
       "%s: unable to create extent values.",
1647
0
       function );
1648
1649
0
      goto on_error;
1650
0
    }
1651
285k
    if( libvmdk_extent_values_read(
1652
285k
         extent_values,
1653
285k
         &( line_string_segment[ line_string_segment_index ] ),
1654
285k
         line_string_segment_size - line_string_segment_index,
1655
285k
         descriptor_file->encoding,
1656
285k
         error ) != 1 )
1657
878
    {
1658
878
      libcerror_error_set(
1659
878
       error,
1660
878
       LIBCERROR_ERROR_DOMAIN_IO,
1661
878
       LIBCERROR_IO_ERROR_READ_FAILED,
1662
878
       "%s: unable to read extent values from line: %d.",
1663
878
       function,
1664
878
       safe_line_index );
1665
1666
878
      goto on_error;
1667
878
    }
1668
/* TODO refactor by get_size function */
1669
285k
    descriptor_file->media_size += extent_values->size;
1670
1671
285k
    if( libcdata_array_append_entry(
1672
285k
         extents_values_array,
1673
285k
         &entry_index,
1674
285k
         (intptr_t *) extent_values,
1675
285k
         error ) != 1 )
1676
0
    {
1677
0
      libcerror_error_set(
1678
0
       error,
1679
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1680
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1681
0
       "%s: unable to append extent values to array.",
1682
0
       function );
1683
1684
0
      goto on_error;
1685
0
    }
1686
285k
    extent_values = NULL;
1687
1688
285k
    safe_line_index++;
1689
285k
  }
1690
1.80k
  *line_index = safe_line_index;
1691
1692
1.80k
  return( 1 );
1693
1694
878
on_error:
1695
878
  if( extent_values != NULL )
1696
878
  {
1697
878
    libvmdk_extent_values_free(
1698
878
     &extent_values,
1699
878
     NULL );
1700
878
  }
1701
878
  libcdata_array_empty(
1702
878
   extents_values_array,
1703
878
   (int (*)(intptr_t **, libcerror_error_t **)) &libvmdk_extent_values_free,
1704
878
   NULL );
1705
1706
878
  return( -1 );
1707
2.68k
}
1708
1709
/* Reads the change tracking file from the descriptor file
1710
 * Returns the 1 if successful, 0 if no such value or -1 on error
1711
 */
1712
int libvmdk_descriptor_file_read_change_tracking_file(
1713
     libvmdk_descriptor_file_t *descriptor_file,
1714
     libcsplit_narrow_split_string_t *lines,
1715
     int number_of_lines,
1716
     int *line_index,
1717
     libcerror_error_t **error )
1718
1.80k
{
1719
1.80k
  char *line_string_segment        = NULL;
1720
1.80k
  char *value_identifier           = NULL;
1721
1.80k
  static char *function            = "libvmdk_descriptor_file_read_change_tracking_file";
1722
1.80k
  size_t line_string_segment_index = 0;
1723
1.80k
  size_t line_string_segment_size  = 0;
1724
1.80k
  size_t value_identifier_length   = 0;
1725
1.80k
  size_t value_length              = 0;
1726
1.80k
  int safe_line_index              = 0;
1727
1728
#if defined( HAVE_DEBUG_OUTPUT )
1729
  char *value                      = NULL;
1730
#endif
1731
1732
1.80k
  if( descriptor_file == NULL )
1733
0
  {
1734
0
    libcerror_error_set(
1735
0
     error,
1736
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1737
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1738
0
     "%s: invalid descriptor file.",
1739
0
     function );
1740
1741
0
    return( -1 );
1742
0
  }
1743
1.80k
  if( line_index == NULL )
1744
0
  {
1745
0
    libcerror_error_set(
1746
0
     error,
1747
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1748
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1749
0
     "%s: invalid line index.",
1750
0
     function );
1751
1752
0
    return( -1 );
1753
0
  }
1754
1.80k
  if( number_of_lines <= 0 )
1755
0
  {
1756
0
    libcerror_error_set(
1757
0
     error,
1758
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1759
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1760
0
     "%s: invalid number of lines value out of bounds.",
1761
0
     function );
1762
1763
0
    return( -1 );
1764
0
  }
1765
1.80k
  safe_line_index = *line_index;
1766
1767
1.80k
  if( ( safe_line_index < 0 )
1768
1.80k
   || ( safe_line_index >= number_of_lines ) )
1769
342
  {
1770
342
    libcerror_error_set(
1771
342
     error,
1772
342
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1773
342
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1774
342
     "%s: invalid line index value out of bounds.",
1775
342
     function );
1776
1777
342
    return( -1 );
1778
342
  }
1779
1.46k
  if( libcsplit_narrow_split_string_get_segment_by_index(
1780
1.46k
       lines,
1781
1.46k
       safe_line_index,
1782
1.46k
       &line_string_segment,
1783
1.46k
       &line_string_segment_size,
1784
1.46k
       error ) != 1 )
1785
0
  {
1786
0
    libcerror_error_set(
1787
0
     error,
1788
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1789
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1790
0
     "%s: unable to retrieve line: %d.",
1791
0
     function,
1792
0
     safe_line_index );
1793
1794
0
    return( -1 );
1795
0
  }
1796
1.46k
  if( line_string_segment == NULL )
1797
0
  {
1798
0
    libcerror_error_set(
1799
0
     error,
1800
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1801
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1802
0
     "%s: missing line string segment: %d.",
1803
0
     function,
1804
0
     safe_line_index );
1805
1806
0
    return( -1 );
1807
0
  }
1808
1.46k
  if( line_string_segment_size < 2 )
1809
0
  {
1810
0
    libcerror_error_set(
1811
0
     error,
1812
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1813
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1814
0
     "%s: invalid line string segment: %d size value out of bounds.",
1815
0
     function,
1816
0
     safe_line_index );
1817
1818
0
    return( -1 );
1819
0
  }
1820
  /* Ignore trailing white space
1821
   */
1822
1.46k
  line_string_segment_index = line_string_segment_size - 2;
1823
1824
58.6k
  while( line_string_segment_index > 0 )
1825
58.6k
  {
1826
58.6k
    if( ( line_string_segment[ line_string_segment_index ] != '\t' )
1827
9.65k
     && ( line_string_segment[ line_string_segment_index ] != '\n' )
1828
9.65k
     && ( line_string_segment[ line_string_segment_index ] != '\f' )
1829
9.15k
     && ( line_string_segment[ line_string_segment_index ] != '\v' )
1830
8.77k
     && ( line_string_segment[ line_string_segment_index ] != '\r' )
1831
5.00k
     && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
1832
1.46k
    {
1833
1.46k
      break;
1834
1.46k
    }
1835
57.1k
    line_string_segment_index--;
1836
57.1k
    line_string_segment_size--;
1837
57.1k
  }
1838
  /* Ignore leading white space
1839
   */
1840
1.46k
  line_string_segment_index = 0;
1841
1842
4.22M
  while( line_string_segment_index < line_string_segment_size )
1843
4.22M
  {
1844
4.22M
    if( ( line_string_segment[ line_string_segment_index ] != '\t' )
1845
3.93M
     && ( line_string_segment[ line_string_segment_index ] != '\n' )
1846
3.93M
     && ( line_string_segment[ line_string_segment_index ] != '\f' )
1847
3.91M
     && ( line_string_segment[ line_string_segment_index ] != '\v' )
1848
3.91M
     && ( line_string_segment[ line_string_segment_index ] != '\r' )
1849
6.56k
     && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
1850
1.46k
    {
1851
1.46k
      break;
1852
1.46k
    }
1853
4.22M
    line_string_segment_index++;
1854
4.22M
  }
1855
1.46k
  if( ( ( line_string_segment_size - line_string_segment_index ) != 23 )
1856
622
   || ( narrow_string_compare_no_case(
1857
622
         &( line_string_segment[ line_string_segment_index ] ),
1858
622
         vmdk_descriptor_file_change_tracking_file_signature,
1859
622
         22 ) != 0 ) )
1860
843
  {
1861
843
    return( 0 );
1862
843
  }
1863
622
  safe_line_index++;
1864
1865
2.64M
  while( safe_line_index < number_of_lines )
1866
2.64M
  {
1867
2.64M
    if( libcsplit_narrow_split_string_get_segment_by_index(
1868
2.64M
         lines,
1869
2.64M
         safe_line_index,
1870
2.64M
         &line_string_segment,
1871
2.64M
         &line_string_segment_size,
1872
2.64M
         error ) != 1 )
1873
0
    {
1874
0
      libcerror_error_set(
1875
0
       error,
1876
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1877
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1878
0
       "%s: unable to retrieve line: %d.",
1879
0
       function,
1880
0
       safe_line_index );
1881
1882
0
      return( -1 );
1883
0
    }
1884
2.64M
    if( line_string_segment == NULL )
1885
0
    {
1886
0
      libcerror_error_set(
1887
0
       error,
1888
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1889
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1890
0
       "%s: missing line string segment: %d.",
1891
0
       function,
1892
0
       safe_line_index );
1893
1894
0
      return( -1 );
1895
0
    }
1896
2.64M
    if( line_string_segment_size < 2 )
1897
2.63M
    {
1898
2.63M
      safe_line_index++;
1899
1900
2.63M
      continue;
1901
2.63M
    }
1902
    /* Ignore trailing white space
1903
     */
1904
4.65k
    line_string_segment_index = line_string_segment_size - 2;
1905
1906
18.7k
    while( line_string_segment_index > 0 )
1907
16.7k
    {
1908
16.7k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
1909
16.0k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
1910
15.7k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
1911
14.9k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
1912
14.5k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
1913
2.85k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
1914
2.62k
      {
1915
2.62k
        break;
1916
2.62k
      }
1917
14.1k
      line_string_segment_index--;
1918
14.1k
      line_string_segment_size--;
1919
14.1k
    }
1920
    /* Ignore leading white space
1921
     */
1922
4.65k
    line_string_segment_index = 0;
1923
1924
135k
    while( line_string_segment_index < line_string_segment_size )
1925
134k
    {
1926
134k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
1927
133k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
1928
133k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
1929
132k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
1930
131k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
1931
4.74k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
1932
4.43k
      {
1933
4.43k
        break;
1934
4.43k
      }
1935
130k
      line_string_segment_index++;
1936
130k
    }
1937
    /* Skip an empty line
1938
     */
1939
4.65k
    if( ( line_string_segment_index >= line_string_segment_size )
1940
4.43k
     || ( line_string_segment[ line_string_segment_index ] == 0 ) )
1941
642
    {
1942
642
      safe_line_index++;
1943
1944
642
      continue;
1945
642
    }
1946
4.01k
    if( ( line_string_segment_size - line_string_segment_index ) == 21 )
1947
387
    {
1948
      /* Check for the end of the section
1949
       */
1950
387
      if( narrow_string_compare_no_case(
1951
387
           &( line_string_segment[ line_string_segment_index ] ),
1952
387
           vmdk_descriptor_file_disk_database_section_signature,
1953
387
           20 ) == 0 )
1954
16
      {
1955
16
        break;
1956
16
      }
1957
387
    }
1958
    /* Determine the value identifier
1959
     */
1960
3.99k
    value_identifier        = &( line_string_segment[ line_string_segment_index ] );
1961
3.99k
    value_identifier_length = 0;
1962
1963
843k
    while( line_string_segment_index < line_string_segment_size )
1964
842k
    {
1965
842k
      if( ( line_string_segment[ line_string_segment_index ] == '\t' )
1966
842k
       || ( line_string_segment[ line_string_segment_index ] == '\n' )
1967
842k
       || ( line_string_segment[ line_string_segment_index ] == '\f' )
1968
842k
       || ( line_string_segment[ line_string_segment_index ] == '\v' )
1969
842k
       || ( line_string_segment[ line_string_segment_index ] == '\r' )
1970
842k
       || ( line_string_segment[ line_string_segment_index ] == ' ' )
1971
841k
       || ( line_string_segment[ line_string_segment_index ] == '=' ) )
1972
3.20k
      {
1973
3.20k
        break;
1974
3.20k
      }
1975
839k
      value_identifier_length++;
1976
1977
839k
      line_string_segment_index++;
1978
839k
    }
1979
    /* Skip a line not containing a value
1980
     */
1981
3.99k
    if( ( line_string_segment_index >= line_string_segment_size )
1982
3.20k
     || ( line_string_segment[ line_string_segment_index ] == 0 ) )
1983
793
    {
1984
793
      safe_line_index++;
1985
1986
793
      continue;
1987
793
    }
1988
    /* Make sure the value identifier is terminated by an end of string
1989
     */
1990
3.20k
    line_string_segment[ line_string_segment_index ] = 0;
1991
1992
3.20k
    line_string_segment_index++;
1993
1994
    /* Ignore whitespace
1995
     */
1996
47.2k
    while( line_string_segment_index < line_string_segment_size )
1997
46.7k
    {
1998
46.7k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
1999
46.0k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
2000
45.5k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
2001
45.0k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
2002
44.8k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
2003
2.90k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
2004
2.65k
      {
2005
2.65k
        break;
2006
2.65k
      }
2007
44.0k
      line_string_segment_index++;
2008
44.0k
    }
2009
3.20k
    if( line_string_segment[ line_string_segment_index ] == '=' )
2010
574
    {
2011
574
      line_string_segment_index++;
2012
2013
26.4k
      while( line_string_segment_index < line_string_segment_size )
2014
26.2k
      {
2015
26.2k
        if( ( line_string_segment[ line_string_segment_index ] != '\t' )
2016
25.8k
         && ( line_string_segment[ line_string_segment_index ] != '\n' )
2017
25.6k
         && ( line_string_segment[ line_string_segment_index ] != '\f' )
2018
25.3k
         && ( line_string_segment[ line_string_segment_index ] != '\v' )
2019
24.7k
         && ( line_string_segment[ line_string_segment_index ] != '\r' )
2020
578
         && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
2021
376
        {
2022
376
          break;
2023
376
        }
2024
25.9k
        line_string_segment_index++;
2025
25.9k
      }
2026
574
    }
2027
    /* Skip a line not containing a value
2028
     */
2029
3.20k
    if( ( line_string_segment_index >= line_string_segment_size )
2030
2.45k
     || ( line_string_segment[ line_string_segment_index ] == 0 ) )
2031
1.34k
    {
2032
1.34k
      safe_line_index++;
2033
2034
1.34k
      continue;
2035
1.34k
    }
2036
    /* Determine the value
2037
     */
2038
#if defined( HAVE_DEBUG_OUTPUT )
2039
    value        = &( line_string_segment[ line_string_segment_index ] );
2040
#endif
2041
1.85k
    value_length = line_string_segment_size - 1;
2042
2043
    /* Ingore quotes at the beginning of the value data
2044
     */
2045
1.85k
    if( ( line_string_segment[ line_string_segment_index ] == '"' )
2046
1.41k
     || ( line_string_segment[ line_string_segment_index ] == '\'' ) )
2047
841
    {
2048
841
      line_string_segment_index++;
2049
#if defined( HAVE_DEBUG_OUTPUT )
2050
      value++;
2051
#endif
2052
841
      value_length--;
2053
841
    }
2054
    /* Ingore quotes at the end of the value data
2055
     */
2056
1.85k
    if( ( line_string_segment[ value_length - 1 ] == '"' )
2057
1.63k
     || ( line_string_segment[ value_length - 1 ] == '\'' ) )
2058
422
    {
2059
422
      value_length--;
2060
422
    }
2061
    /* Make sure the value is terminated by an end of string
2062
     */
2063
1.85k
    line_string_segment[ value_length ] = 0;
2064
2065
#if defined( HAVE_DEBUG_OUTPUT )
2066
    value_length -= line_string_segment_index;
2067
#endif
2068
1.85k
    if( value_identifier_length == 15 )
2069
1
    {
2070
1
      if( narrow_string_compare_no_case(
2071
1
           value_identifier,
2072
1
           "changeTrackPath",
2073
1
           15 ) == 0 )
2074
0
      {
2075
/* TODO */
2076
0
      }
2077
1
    }
2078
#if defined( HAVE_DEBUG_OUTPUT )
2079
    else if( libcnotify_verbose != 0 )
2080
    {
2081
      libcnotify_printf(
2082
       "%s: value: %d\t\t\t\t: %s = %s\n",
2083
       function,
2084
       safe_line_index,
2085
       value_identifier,
2086
       value );
2087
    }
2088
#endif
2089
1.85k
    safe_line_index++;
2090
1.85k
  }
2091
#if defined( HAVE_DEBUG_OUTPUT )
2092
  if( libcnotify_verbose != 0 )
2093
  {
2094
    libcnotify_printf(
2095
     "\n" );
2096
  }
2097
#endif
2098
622
  *line_index = safe_line_index;
2099
2100
622
  return( 1 );
2101
622
}
2102
2103
/* Reads the disk database from the descriptor file
2104
 * Returns the 1 if successful or -1 on error
2105
 */
2106
int libvmdk_descriptor_file_read_disk_database(
2107
     libvmdk_descriptor_file_t *descriptor_file,
2108
     libcsplit_narrow_split_string_t *lines,
2109
     int number_of_lines,
2110
     int *line_index,
2111
     libcerror_error_t **error )
2112
1.46k
{
2113
1.46k
  char *line_string_segment        = NULL;
2114
1.46k
  char *value_identifier           = NULL;
2115
1.46k
  static char *function            = "libvmdk_descriptor_file_read_disk_database";
2116
1.46k
  size_t line_string_segment_index = 0;
2117
1.46k
  size_t line_string_segment_size  = 0;
2118
1.46k
  size_t value_identifier_length   = 0;
2119
1.46k
  size_t value_length              = 0;
2120
1.46k
  int safe_line_index              = 0;
2121
2122
#if defined( HAVE_DEBUG_OUTPUT )
2123
  char *value                      = NULL;
2124
#endif
2125
2126
1.46k
  if( descriptor_file == NULL )
2127
0
  {
2128
0
    libcerror_error_set(
2129
0
     error,
2130
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2131
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2132
0
     "%s: invalid descriptor file.",
2133
0
     function );
2134
2135
0
    return( -1 );
2136
0
  }
2137
1.46k
  if( line_index == NULL )
2138
0
  {
2139
0
    libcerror_error_set(
2140
0
     error,
2141
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2142
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2143
0
     "%s: invalid line index.",
2144
0
     function );
2145
2146
0
    return( -1 );
2147
0
  }
2148
1.46k
  if( number_of_lines <= 0 )
2149
0
  {
2150
0
    libcerror_error_set(
2151
0
     error,
2152
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2153
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2154
0
     "%s: invalid number of lines value out of bounds.",
2155
0
     function );
2156
2157
0
    return( -1 );
2158
0
  }
2159
1.46k
  safe_line_index = *line_index;
2160
2161
1.46k
  if( ( safe_line_index < 0 )
2162
1.46k
   || ( safe_line_index >= number_of_lines ) )
2163
606
  {
2164
606
    libcerror_error_set(
2165
606
     error,
2166
606
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2167
606
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2168
606
     "%s: invalid line index value out of bounds.",
2169
606
     function );
2170
2171
606
    return( -1 );
2172
606
  }
2173
859
  if( libcsplit_narrow_split_string_get_segment_by_index(
2174
859
       lines,
2175
859
       safe_line_index,
2176
859
       &line_string_segment,
2177
859
       &line_string_segment_size,
2178
859
       error ) != 1 )
2179
0
  {
2180
0
    libcerror_error_set(
2181
0
     error,
2182
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2183
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2184
0
     "%s: unable to retrieve line: %d.",
2185
0
     function,
2186
0
     safe_line_index );
2187
2188
0
    return( -1 );
2189
0
  }
2190
859
  if( line_string_segment == NULL )
2191
0
  {
2192
0
    libcerror_error_set(
2193
0
     error,
2194
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2195
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2196
0
     "%s: missing line string segment: %d.",
2197
0
     function,
2198
0
     safe_line_index );
2199
2200
0
    return( -1 );
2201
0
  }
2202
859
  if( line_string_segment_size < 2 )
2203
0
  {
2204
0
    libcerror_error_set(
2205
0
     error,
2206
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2207
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2208
0
     "%s: invalid line string segment: %d size value out of bounds.",
2209
0
     function,
2210
0
     safe_line_index );
2211
2212
0
    return( -1 );
2213
0
  }
2214
  /* Ignore trailing white space
2215
   */
2216
859
  line_string_segment_index = line_string_segment_size - 2;
2217
2218
25.2k
  while( line_string_segment_index > 0 )
2219
25.2k
  {
2220
25.2k
    if( ( line_string_segment[ line_string_segment_index ] != '\t' )
2221
9.03k
     && ( line_string_segment[ line_string_segment_index ] != '\n' )
2222
9.03k
     && ( line_string_segment[ line_string_segment_index ] != '\f' )
2223
8.54k
     && ( line_string_segment[ line_string_segment_index ] != '\v' )
2224
8.17k
     && ( line_string_segment[ line_string_segment_index ] != '\r' )
2225
4.39k
     && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
2226
859
    {
2227
859
      break;
2228
859
    }
2229
24.3k
    line_string_segment_index--;
2230
24.3k
    line_string_segment_size--;
2231
24.3k
  }
2232
  /* Ignore leading white space
2233
   */
2234
859
  line_string_segment_index = 0;
2235
2236
3.96M
  while( line_string_segment_index < line_string_segment_size )
2237
3.96M
  {
2238
3.96M
    if( ( line_string_segment[ line_string_segment_index ] != '\t' )
2239
3.93M
     && ( line_string_segment[ line_string_segment_index ] != '\n' )
2240
3.93M
     && ( line_string_segment[ line_string_segment_index ] != '\f' )
2241
3.91M
     && ( line_string_segment[ line_string_segment_index ] != '\v' )
2242
3.91M
     && ( line_string_segment[ line_string_segment_index ] != '\r' )
2243
5.95k
     && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
2244
859
    {
2245
859
      break;
2246
859
    }
2247
3.96M
    line_string_segment_index++;
2248
3.96M
  }
2249
859
  if( ( ( line_string_segment_size - line_string_segment_index ) != 21 )
2250
859
   || ( narrow_string_compare_no_case(
2251
859
         &( line_string_segment[ line_string_segment_index ] ),
2252
859
         vmdk_descriptor_file_disk_database_section_signature,
2253
859
         20 ) != 0 ) )
2254
0
  {
2255
0
    libcerror_error_set(
2256
0
     error,
2257
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2258
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2259
0
     "%s: unsupported disk database section signature.",
2260
0
     function );
2261
2262
0
    return( -1 );
2263
0
  }
2264
859
  safe_line_index++;
2265
2266
421k
  while( safe_line_index < number_of_lines )
2267
420k
  {
2268
420k
    if( libcsplit_narrow_split_string_get_segment_by_index(
2269
420k
         lines,
2270
420k
         safe_line_index,
2271
420k
         &line_string_segment,
2272
420k
         &line_string_segment_size,
2273
420k
         error ) != 1 )
2274
0
    {
2275
0
      libcerror_error_set(
2276
0
       error,
2277
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2278
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2279
0
       "%s: unable to retrieve line: %d.",
2280
0
       function,
2281
0
       safe_line_index );
2282
2283
0
      return( -1 );
2284
0
    }
2285
420k
    if( line_string_segment == NULL )
2286
0
    {
2287
0
      libcerror_error_set(
2288
0
       error,
2289
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2290
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2291
0
       "%s: missing line string segment: %d.",
2292
0
       function,
2293
0
       safe_line_index );
2294
2295
0
      return( -1 );
2296
0
    }
2297
420k
    if( line_string_segment_size < 2 )
2298
413k
    {
2299
413k
      safe_line_index++;
2300
2301
413k
      continue;
2302
413k
    }
2303
    /* Ignore trailing white space
2304
     */
2305
7.10k
    line_string_segment_index = line_string_segment_size - 2;
2306
2307
19.6k
    while( line_string_segment_index > 0 )
2308
17.3k
    {
2309
17.3k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
2310
14.4k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
2311
13.9k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
2312
13.2k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
2313
12.6k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
2314
4.95k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
2315
4.75k
      {
2316
4.75k
        break;
2317
4.75k
      }
2318
12.5k
      line_string_segment_index--;
2319
12.5k
      line_string_segment_size--;
2320
12.5k
    }
2321
    /* Ignore leading white space
2322
     */
2323
7.10k
    line_string_segment_index = 0;
2324
2325
788k
    while( line_string_segment_index < line_string_segment_size )
2326
788k
    {
2327
788k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
2328
783k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
2329
783k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
2330
778k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
2331
778k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
2332
6.90k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
2333
6.66k
      {
2334
6.66k
        break;
2335
6.66k
      }
2336
781k
      line_string_segment_index++;
2337
781k
    }
2338
    /* Skip an empty line
2339
     */
2340
7.10k
    if( ( line_string_segment_index >= line_string_segment_size )
2341
6.66k
     || ( line_string_segment[ line_string_segment_index ] == 0 ) )
2342
759
    {
2343
759
      safe_line_index++;
2344
2345
759
      continue;
2346
759
    }
2347
    /* Determine the value identifier
2348
     */
2349
6.34k
    value_identifier        = &( line_string_segment[ line_string_segment_index ] );
2350
6.34k
    value_identifier_length = 0;
2351
2352
761k
    while( line_string_segment_index < line_string_segment_size )
2353
760k
    {
2354
760k
      if( ( line_string_segment[ line_string_segment_index ] == '\t' )
2355
760k
       || ( line_string_segment[ line_string_segment_index ] == '\n' )
2356
760k
       || ( line_string_segment[ line_string_segment_index ] == '\f' )
2357
760k
       || ( line_string_segment[ line_string_segment_index ] == '\v' )
2358
759k
       || ( line_string_segment[ line_string_segment_index ] == '\r' )
2359
759k
       || ( line_string_segment[ line_string_segment_index ] == ' ' )
2360
758k
       || ( line_string_segment[ line_string_segment_index ] == '=' ) )
2361
5.03k
      {
2362
5.03k
        break;
2363
5.03k
      }
2364
755k
      value_identifier_length++;
2365
2366
755k
      line_string_segment_index++;
2367
755k
    }
2368
    /* Skip a line not containing a value
2369
     */
2370
6.34k
    if( ( line_string_segment_index >= line_string_segment_size )
2371
5.03k
     || ( line_string_segment[ line_string_segment_index ] == 0 ) )
2372
1.30k
    {
2373
1.30k
      safe_line_index++;
2374
2375
1.30k
      continue;
2376
1.30k
    }
2377
    /* Make sure the value identifier is terminated by an end of string
2378
     */
2379
5.03k
    line_string_segment[ line_string_segment_index ] = 0;
2380
2381
5.03k
    line_string_segment_index++;
2382
2383
    /* Ignore whitespace
2384
     */
2385
67.3k
    while( line_string_segment_index < line_string_segment_size )
2386
66.7k
    {
2387
66.7k
      if( ( line_string_segment[ line_string_segment_index ] != '\t' )
2388
49.0k
       && ( line_string_segment[ line_string_segment_index ] != '\n' )
2389
48.8k
       && ( line_string_segment[ line_string_segment_index ] != '\f' )
2390
48.3k
       && ( line_string_segment[ line_string_segment_index ] != '\v' )
2391
47.7k
       && ( line_string_segment[ line_string_segment_index ] != '\r' )
2392
5.82k
       && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
2393
4.42k
      {
2394
4.42k
        break;
2395
4.42k
      }
2396
62.3k
      line_string_segment_index++;
2397
62.3k
    }
2398
5.03k
    if( line_string_segment[ line_string_segment_index ] == '=' )
2399
547
    {
2400
547
      line_string_segment_index++;
2401
2402
5.85k
      while( line_string_segment_index < line_string_segment_size )
2403
5.64k
      {
2404
5.64k
        if( ( line_string_segment[ line_string_segment_index ] != '\t' )
2405
5.24k
         && ( line_string_segment[ line_string_segment_index ] != '\n' )
2406
5.02k
         && ( line_string_segment[ line_string_segment_index ] != '\f' )
2407
4.80k
         && ( line_string_segment[ line_string_segment_index ] != '\v' )
2408
4.49k
         && ( line_string_segment[ line_string_segment_index ] != '\r' )
2409
541
         && ( line_string_segment[ line_string_segment_index ] != ' ' ) )
2410
342
        {
2411
342
          break;
2412
342
        }
2413
5.30k
        line_string_segment_index++;
2414
5.30k
      }
2415
547
    }
2416
    /* Skip a line not containing a value
2417
     */
2418
5.03k
    if( ( line_string_segment_index >= line_string_segment_size )
2419
4.22k
     || ( line_string_segment[ line_string_segment_index ] == 0 ) )
2420
1.28k
    {
2421
1.28k
      safe_line_index++;
2422
2423
1.28k
      continue;
2424
1.28k
    }
2425
    /* Determine the value
2426
     */
2427
#if defined( HAVE_DEBUG_OUTPUT )
2428
    value        = &( line_string_segment[ line_string_segment_index ] );
2429
#endif
2430
3.74k
    value_length = line_string_segment_size - 1;
2431
2432
    /* Ingore quotes at the beginning of the value data
2433
     */
2434
3.74k
    if( ( line_string_segment[ line_string_segment_index ] == '"' )
2435
3.33k
     || ( line_string_segment[ line_string_segment_index ] == '\'' ) )
2436
803
    {
2437
803
      line_string_segment_index++;
2438
#if defined( HAVE_DEBUG_OUTPUT )
2439
      value++;
2440
#endif
2441
803
      value_length--;
2442
803
    }
2443
    /* Ingore quotes at the end of the value data
2444
     */
2445
3.74k
    if( ( line_string_segment[ value_length - 1 ] == '"' )
2446
2.38k
     || ( line_string_segment[ value_length - 1 ] == '\'' ) )
2447
1.55k
    {
2448
1.55k
      value_length--;
2449
1.55k
    }
2450
    /* Make sure the value is terminated by an end of string
2451
     */
2452
3.74k
    line_string_segment[ value_length ] = 0;
2453
2454
#if defined( HAVE_DEBUG_OUTPUT )
2455
    value_length -= line_string_segment_index;
2456
#endif
2457
3.74k
    if( value_identifier_length == 15 )
2458
0
    {
2459
0
      if( narrow_string_compare_no_case(
2460
0
           value_identifier,
2461
0
           "ddb.adapterType",
2462
0
           15 ) == 0 )
2463
0
      {
2464
/* TODO */
2465
0
      }
2466
0
    }
2467
3.74k
    else if( value_identifier_length == 16 )
2468
15
    {
2469
15
      if( narrow_string_compare_no_case(
2470
15
           value_identifier,
2471
15
           "ddb.toolsVersion",
2472
15
           16 ) == 0 )
2473
0
      {
2474
/* TODO */
2475
0
      }
2476
15
    }
2477
3.73k
    else if( value_identifier_length == 18 )
2478
1
    {
2479
1
      if( narrow_string_compare_no_case(
2480
1
           value_identifier,
2481
1
           "ddb.geometry.heads",
2482
1
           18 ) == 0 )
2483
0
      {
2484
/* TODO */
2485
0
      }
2486
1
    }
2487
3.73k
    else if( value_identifier_length == 20 )
2488
10
    {
2489
10
      if( narrow_string_compare_no_case(
2490
10
           value_identifier,
2491
10
           "ddb.geometry.sectors",
2492
10
           20 ) == 0 )
2493
0
      {
2494
/* TODO */
2495
0
      }
2496
10
      else if( narrow_string_compare_no_case(
2497
10
                value_identifier,
2498
10
                "ddb.virtualHWVersion",
2499
10
                20 ) == 0 )
2500
0
      {
2501
/* TODO */
2502
0
      }
2503
10
    }
2504
3.72k
    else if( value_identifier_length == 22 )
2505
1
    {
2506
1
      if( narrow_string_compare_no_case(
2507
1
           value_identifier,
2508
1
           "ddb.geometry.cylinders",
2509
1
           22 ) == 0 )
2510
0
      {
2511
/* TODO */
2512
0
      }
2513
1
    }
2514
#if defined( HAVE_DEBUG_OUTPUT )
2515
    else if( libcnotify_verbose != 0 )
2516
    {
2517
      libcnotify_printf(
2518
       "%s: value: %d\t\t\t: %s = %s\n",
2519
       function,
2520
       safe_line_index,
2521
       value_identifier,
2522
       value );
2523
    }
2524
#endif
2525
3.74k
    safe_line_index++;
2526
3.74k
  }
2527
#if defined( HAVE_DEBUG_OUTPUT )
2528
  if( libcnotify_verbose != 0 )
2529
  {
2530
    libcnotify_printf(
2531
     "\n" );
2532
  }
2533
#endif
2534
859
  *line_index = safe_line_index;
2535
2536
859
  return( 1 );
2537
859
}
2538
2539
/* Retrieves the parent content identifier
2540
 * Returns 1 if successful, 0 if not available or -1 on error
2541
 */
2542
int libvmdk_descriptor_file_get_parent_content_identifier(
2543
     libvmdk_descriptor_file_t *descriptor_file,
2544
     uint32_t *parent_content_identifier,
2545
     libcerror_error_t **error )
2546
859
{
2547
859
  static char *function = "libvmdk_descriptor_file_get_parent_content_identifier";
2548
2549
859
  if( descriptor_file == NULL )
2550
0
  {
2551
0
    libcerror_error_set(
2552
0
     error,
2553
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2554
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2555
0
     "%s: invalid descriptor file.",
2556
0
     function );
2557
2558
0
    return( -1 );
2559
0
  }
2560
859
  if( parent_content_identifier == NULL )
2561
0
  {
2562
0
    libcerror_error_set(
2563
0
     error,
2564
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2565
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2566
0
     "%s: invalid parent content identifier.",
2567
0
     function );
2568
2569
0
    return( -1 );
2570
0
  }
2571
859
  if( descriptor_file->parent_content_identifier_set == 0 )
2572
858
  {
2573
858
    return( 0 );
2574
858
  }
2575
1
  *parent_content_identifier = descriptor_file->parent_content_identifier;
2576
2577
1
  return( 1 );
2578
859
}
2579
2580
/* Retrieves the size of the UTF-8 encoded parent filename
2581
 * The returned size includes the end of string character
2582
 * Returns 1 if successful, 0 if not available or -1 on error
2583
 */
2584
int libvmdk_descriptor_file_get_utf8_parent_filename_size(
2585
     libvmdk_descriptor_file_t *descriptor_file,
2586
     size_t *utf8_string_size,
2587
     libcerror_error_t **error )
2588
859
{
2589
859
  static char *function = "libvmdk_descriptor_file_get_utf8_parent_filename_size";
2590
2591
859
  if( descriptor_file == NULL )
2592
0
  {
2593
0
    libcerror_error_set(
2594
0
     error,
2595
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2596
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2597
0
     "%s: invalid descriptor file.",
2598
0
     function );
2599
2600
0
    return( -1 );
2601
0
  }
2602
859
  if( ( descriptor_file->parent_filename == NULL )
2603
285
   || ( descriptor_file->parent_filename_size == 0 ) )
2604
574
  {
2605
574
    return( 0 );
2606
574
  }
2607
285
  if( libuna_utf8_string_size_from_utf8_stream(
2608
285
       descriptor_file->parent_filename,
2609
285
       descriptor_file->parent_filename_size,
2610
285
       utf8_string_size,
2611
285
       error ) != 1 )
2612
94
  {
2613
94
    libcerror_error_set(
2614
94
     error,
2615
94
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2616
94
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2617
94
     "%s: unable to retrieve UTF-8 string size.",
2618
94
     function );
2619
2620
94
    return( -1 );
2621
94
  }
2622
191
  return( 1 );
2623
285
}
2624
2625
/* Retrieves the UTF-8 encoded parent filename
2626
 * The size should include the end of string character
2627
 * Returns 1 if successful, 0 if not available or -1 on error
2628
 */
2629
int libvmdk_descriptor_file_get_utf8_parent_filename(
2630
     libvmdk_descriptor_file_t *descriptor_file,
2631
     uint8_t *utf8_string,
2632
     size_t utf8_string_size,
2633
     libcerror_error_t **error )
2634
765
{
2635
765
  static char *function = "libvmdk_descriptor_file_get_utf8_parent_filename";
2636
2637
765
  if( descriptor_file == NULL )
2638
0
  {
2639
0
    libcerror_error_set(
2640
0
     error,
2641
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2642
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2643
0
     "%s: invalid descriptor file.",
2644
0
     function );
2645
2646
0
    return( -1 );
2647
0
  }
2648
765
  if( ( descriptor_file->parent_filename == NULL )
2649
191
   || ( descriptor_file->parent_filename_size == 0 ) )
2650
574
  {
2651
574
    return( 0 );
2652
574
  }
2653
191
  if( libuna_utf8_string_copy_from_utf8_stream(
2654
191
       utf8_string,
2655
191
       utf8_string_size,
2656
191
       descriptor_file->parent_filename,
2657
191
       descriptor_file->parent_filename_size,
2658
191
       error ) != 1 )
2659
57
  {
2660
57
    libcerror_error_set(
2661
57
     error,
2662
57
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2663
57
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2664
57
     "%s: unable to copy parent filename to UTF-8 string.",
2665
57
     function );
2666
2667
57
    return( -1 );
2668
57
  }
2669
134
  return( 1 );
2670
191
}
2671
2672
/* Retrieves the size of the UTF-16 encoded parent filename
2673
 * The returned size includes the end of string character
2674
 * Returns 1 if successful, 0 if not available or -1 on error
2675
 */
2676
int libvmdk_descriptor_file_get_utf16_parent_filename_size(
2677
     libvmdk_descriptor_file_t *descriptor_file,
2678
     size_t *utf16_string_size,
2679
     libcerror_error_t **error )
2680
708
{
2681
708
  static char *function = "libvmdk_descriptor_file_get_utf16_parent_filename_size";
2682
2683
708
  if( descriptor_file == NULL )
2684
0
  {
2685
0
    libcerror_error_set(
2686
0
     error,
2687
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2688
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2689
0
     "%s: invalid descriptor file.",
2690
0
     function );
2691
2692
0
    return( -1 );
2693
0
  }
2694
708
  if( ( descriptor_file->parent_filename == NULL )
2695
134
   || ( descriptor_file->parent_filename_size == 0 ) )
2696
574
  {
2697
574
    return( 0 );
2698
574
  }
2699
134
  if( libuna_utf16_string_size_from_utf8_stream(
2700
134
       descriptor_file->parent_filename,
2701
134
       descriptor_file->parent_filename_size,
2702
134
       utf16_string_size,
2703
134
       error ) != 1 )
2704
0
  {
2705
0
    libcerror_error_set(
2706
0
     error,
2707
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2708
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2709
0
     "%s: unable to retrieve UTF-16 string size.",
2710
0
     function );
2711
2712
0
    return( -1 );
2713
0
  }
2714
134
  return( 1 );
2715
134
}
2716
2717
/* Retrieves the UTF-16 encoded parent filename
2718
 * The size should include the end of string character
2719
 * Returns 1 if successful, 0 if not available or -1 on error
2720
 */
2721
int libvmdk_descriptor_file_get_utf16_parent_filename(
2722
     libvmdk_descriptor_file_t *descriptor_file,
2723
     uint16_t *utf16_string,
2724
     size_t utf16_string_size,
2725
     libcerror_error_t **error )
2726
708
{
2727
708
  static char *function = "libvmdk_descriptor_file_get_utf16_parent_filename";
2728
2729
708
  if( descriptor_file == NULL )
2730
0
  {
2731
0
    libcerror_error_set(
2732
0
     error,
2733
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2734
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2735
0
     "%s: invalid descriptor file.",
2736
0
     function );
2737
2738
0
    return( -1 );
2739
0
  }
2740
708
  if( ( descriptor_file->parent_filename == NULL )
2741
134
   || ( descriptor_file->parent_filename_size == 0 ) )
2742
574
  {
2743
574
    return( 0 );
2744
574
  }
2745
134
  if( libuna_utf16_string_copy_from_utf8_stream(
2746
134
       utf16_string,
2747
134
       utf16_string_size,
2748
134
       descriptor_file->parent_filename,
2749
134
       descriptor_file->parent_filename_size,
2750
134
       error ) != 1 )
2751
0
  {
2752
0
    libcerror_error_set(
2753
0
     error,
2754
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2755
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2756
0
     "%s: unable to copy parent filename to UTF-16 string.",
2757
0
     function );
2758
2759
0
    return( -1 );
2760
0
  }
2761
134
  return( 1 );
2762
134
}
2763
2764
/* Retrieves the disk type
2765
 * Returns 1 if successful or -1 on error
2766
 */
2767
int libvmdk_descriptor_file_get_disk_type(
2768
     libvmdk_descriptor_file_t *descriptor_file,
2769
     int *disk_type,
2770
     libcerror_error_t **error )
2771
860
{
2772
860
  static char *function = "libvmdk_descriptor_file_get_disk_type";
2773
2774
860
  if( descriptor_file == NULL )
2775
1
  {
2776
1
    libcerror_error_set(
2777
1
     error,
2778
1
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2779
1
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2780
1
     "%s: invalid descriptor file.",
2781
1
     function );
2782
2783
1
    return( -1 );
2784
1
  }
2785
859
  if( disk_type == NULL )
2786
0
  {
2787
0
    libcerror_error_set(
2788
0
     error,
2789
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2790
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2791
0
     "%s: invalid disk type.",
2792
0
     function );
2793
2794
0
    return( -1 );
2795
0
  }
2796
859
  *disk_type = descriptor_file->disk_type;
2797
2798
859
  return( 1 );
2799
859
}
2800
2801
/* Retrieves the media size
2802
 * Returns 1 if successful or -1 on error
2803
 */
2804
int libvmdk_descriptor_file_get_media_size(
2805
     libvmdk_descriptor_file_t *descriptor_file,
2806
     size64_t *media_size,
2807
     libcerror_error_t **error )
2808
859
{
2809
859
  static char *function = "libvmdk_descriptor_file_get_media_size";
2810
2811
859
  if( descriptor_file == NULL )
2812
0
  {
2813
0
    libcerror_error_set(
2814
0
     error,
2815
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2816
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2817
0
     "%s: invalid descriptor file.",
2818
0
     function );
2819
2820
0
    return( -1 );
2821
0
  }
2822
859
  if( media_size == NULL )
2823
0
  {
2824
0
    libcerror_error_set(
2825
0
     error,
2826
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2827
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2828
0
     "%s: invalid media size.",
2829
0
     function );
2830
2831
0
    return( -1 );
2832
0
  }
2833
859
  *media_size = descriptor_file->media_size;
2834
2835
859
  return( 1 );
2836
859
}
2837