Coverage Report

Created: 2023-06-07 06:53

/src/libodraw/libodraw/libodraw_io_handle.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Input/Output (IO) handle functions
3
 *
4
 * Copyright (C) 2010-2023, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libodraw_definitions.h"
27
#include "libodraw_codepage.h"
28
#include "libodraw_io_handle.h"
29
#include "libodraw_libcerror.h"
30
#include "libodraw_libcnotify.h"
31
32
#define libodraw_optical_disk_copy_msf_to_lba( minutes, seconds, frames, lba ) \
33
0
  lba  = minutes; \
34
0
  lba *= 60; \
35
0
  lba += seconds; \
36
0
  lba *= 75; \
37
0
  lba += frames; \
38
0
  lba -= 150;
39
40
static uint8_t libodraw_sector_synchronisation_data[ 12 ] = \
41
  { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
42
43
/* Creates an IO handle
44
 * Make sure the value io_handle is referencing, is set to NULL
45
 * Returns 1 if successful or -1 on error
46
 */
47
int libodraw_io_handle_initialize(
48
     libodraw_io_handle_t **io_handle,
49
     libcerror_error_t **error )
50
1.50k
{
51
1.50k
  static char *function = "libodraw_io_handle_initialize";
52
53
1.50k
  if( io_handle == NULL )
54
0
  {
55
0
    libcerror_error_set(
56
0
     error,
57
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
58
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
59
0
     "%s: invalid IO handle.",
60
0
     function );
61
62
0
    return( -1 );
63
0
  }
64
1.50k
  if( *io_handle != NULL )
65
0
  {
66
0
    libcerror_error_set(
67
0
     error,
68
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
69
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
70
0
     "%s: invalid IO handle value already set.",
71
0
     function );
72
73
0
    return( -1 );
74
0
  }
75
1.50k
  *io_handle = memory_allocate_structure(
76
1.50k
                libodraw_io_handle_t );
77
78
1.50k
  if( *io_handle == NULL )
79
0
  {
80
0
    libcerror_error_set(
81
0
     error,
82
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
83
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
84
0
     "%s: unable to create IO handle.",
85
0
     function );
86
87
0
    goto on_error;
88
0
  }
89
1.50k
  if( memory_set(
90
1.50k
       *io_handle,
91
1.50k
       0,
92
1.50k
       sizeof( libodraw_io_handle_t ) ) == NULL )
93
0
  {
94
0
    libcerror_error_set(
95
0
     error,
96
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
97
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
98
0
     "%s: unable to clear file.",
99
0
     function );
100
101
0
    goto on_error;
102
0
  }
103
1.50k
  ( *io_handle )->bytes_per_sector = 2048;
104
1.50k
  ( *io_handle )->ascii_codepage   = LIBODRAW_CODEPAGE_WINDOWS_1252;
105
106
1.50k
  return( 1 );
107
108
0
on_error:
109
0
  if( *io_handle != NULL )
110
0
  {
111
0
    memory_free(
112
0
     *io_handle );
113
114
0
    *io_handle = NULL;
115
0
  }
116
0
  return( -1 );
117
1.50k
}
118
119
/* Frees an IO handle
120
 * Returns 1 if successful or -1 on error
121
 */
122
int libodraw_io_handle_free(
123
     libodraw_io_handle_t **io_handle,
124
     libcerror_error_t **error )
125
1.50k
{
126
1.50k
  static char *function = "libodraw_io_handle_free";
127
128
1.50k
  if( io_handle == NULL )
129
0
  {
130
0
    libcerror_error_set(
131
0
     error,
132
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
133
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
134
0
     "%s: invalid IO handle.",
135
0
     function );
136
137
0
    return( -1 );
138
0
  }
139
1.50k
  if( *io_handle != NULL )
140
1.50k
  {
141
1.50k
    memory_free(
142
1.50k
     *io_handle );
143
144
1.50k
    *io_handle = NULL;
145
1.50k
  }
146
1.50k
  return( 1 );
147
1.50k
}
148
149
/* Clears the IO handle
150
 * Returns 1 if successful or -1 on error
151
 */
152
int libodraw_io_handle_clear(
153
     libodraw_io_handle_t *io_handle,
154
     libcerror_error_t **error )
155
759
{
156
759
  static char *function = "libodraw_io_handle_clear";
157
158
759
  if( io_handle == NULL )
159
0
  {
160
0
    libcerror_error_set(
161
0
     error,
162
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
163
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
164
0
     "%s: invalid IO handle.",
165
0
     function );
166
167
0
    return( -1 );
168
0
  }
169
759
  if( memory_set(
170
759
       io_handle,
171
759
       0,
172
759
       sizeof( libodraw_io_handle_t ) ) == NULL )
173
0
  {
174
0
    libcerror_error_set(
175
0
     error,
176
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
177
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
178
0
     "%s: unable to clear IO handle.",
179
0
     function );
180
181
0
    return( -1 );
182
0
  }
183
759
  io_handle->bytes_per_sector = 2048;
184
759
  io_handle->ascii_codepage   = LIBODRAW_CODEPAGE_WINDOWS_1252;
185
186
759
  return( 1 );
187
759
}
188
189
/* Copies the sector data to the buffer
190
 * Returns the number of bytes copied if successful or -1 on error
191
 */
192
ssize_t libodraw_io_handle_copy_sector_data_to_buffer(
193
         libodraw_io_handle_t *io_handle,
194
         const uint8_t *sector_data,
195
         size_t sector_data_size,
196
         uint32_t bytes_per_sector,
197
         uint8_t track_type,
198
         uint8_t *buffer,
199
         size_t buffer_size,
200
         uint32_t sector_index,
201
         uint32_t sector_offset,
202
         libcerror_error_t **error )
203
0
{
204
0
  static char *function     = "libodraw_io_handle_copy_sector_data_to_buffer";
205
0
  size_t buffer_offset      = 0;
206
0
  size_t read_size          = 0;
207
0
  size_t sector_data_offset = 0;
208
0
  uint32_t sector_lba       = 0;
209
210
#if defined( HAVE_DEBUG_OUTPUT ) || defined( HAVE_VERBOSE_OUTPUT )
211
  uint8_t sector_mode       = 0;
212
#endif
213
214
0
  if( io_handle == NULL )
215
0
  {
216
0
    libcerror_error_set(
217
0
     error,
218
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
219
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
220
0
     "%s: invalid IO handle.",
221
0
     function );
222
223
0
    return( -1 );
224
0
  }
225
0
  if( sector_data == NULL )
226
0
  {
227
0
    libcerror_error_set(
228
0
     error,
229
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
230
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
231
0
     "%s: invalid sector data.",
232
0
     function );
233
234
0
    return( -1 );
235
0
  }
236
0
  if( sector_data_size > (size_t) SSIZE_MAX )
237
0
  {
238
0
    libcerror_error_set(
239
0
     error,
240
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
241
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
242
0
     "%s: invalid sector data size value exceeds maximum.",
243
0
     function );
244
245
0
    return( -1 );
246
0
  }
247
0
  if( buffer == NULL )
248
0
  {
249
0
    libcerror_error_set(
250
0
     error,
251
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
252
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
253
0
     "%s: invalid buffer.",
254
0
     function );
255
256
0
    return( -1 );
257
0
  }
258
0
  if( buffer_size > (size_t) SSIZE_MAX )
259
0
  {
260
0
    libcerror_error_set(
261
0
     error,
262
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
263
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
264
0
     "%s: invalid buffer size value exceeds maximum.",
265
0
     function );
266
267
0
    return( -1 );
268
0
  }
269
0
  if( ( (size_t) sector_offset >= sector_data_size )
270
0
   || ( sector_offset >= io_handle->bytes_per_sector ) )
271
0
  {
272
0
    libcerror_error_set(
273
0
     error,
274
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
275
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
276
0
     "%s: invalid sector offset value out of bounds.",
277
0
     function );
278
279
0
    return( -1 );
280
0
  }
281
0
  while( sector_data_offset < sector_data_size )
282
0
  {
283
0
    if( io_handle->bytes_per_sector == 2048 )
284
0
    {
285
0
      if( ( track_type == LIBODRAW_TRACK_TYPE_MODE1_2352 )
286
0
       || ( track_type == LIBODRAW_TRACK_TYPE_MODE2_2352 ) )
287
0
      {
288
0
        if( ( sector_data_offset + 16 ) >= sector_data_size )
289
0
        {
290
0
          libcerror_error_set(
291
0
           error,
292
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
293
0
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
294
0
           "%s: sector data too small.",
295
0
           function );
296
297
0
          return( -1 );
298
0
        }
299
#if defined( HAVE_DEBUG_OUTPUT )
300
        if( libcnotify_verbose != 0 )
301
        {
302
          libcnotify_printf(
303
           "%s: sector: %" PRIu32 " header:\n",
304
           function,
305
           sector_index );
306
          libcnotify_print_data(
307
           &( sector_data[ sector_data_offset ] ),
308
           16,
309
           0 );
310
        }
311
#endif
312
0
        if( memory_compare(
313
0
             &( sector_data[ sector_data_offset ] ),
314
0
             libodraw_sector_synchronisation_data,
315
0
             12 ) != 0 )
316
0
        {
317
0
          libcerror_error_set(
318
0
           error,
319
0
           LIBCERROR_ERROR_DOMAIN_INPUT,
320
0
           LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
321
0
           "%s: unsupported sector synchronisation data.",
322
0
           function );
323
324
0
          return( -1 );
325
0
        }
326
#if defined( HAVE_DEBUG_OUTPUT )
327
        if( libcnotify_verbose != 0 )
328
        {
329
          libcnotify_printf(
330
           "%s: sector: %" PRIu32 " synchronisation data:\n",
331
           function,
332
           sector_index );
333
          libcnotify_print_data(
334
           &( sector_data[ sector_data_offset ] ),
335
           12,
336
           0 );
337
        }
338
#endif
339
0
        sector_data_offset += 12;
340
341
0
        libodraw_optical_disk_copy_msf_to_lba(
342
0
         sector_data[ sector_data_offset ],
343
0
         sector_data[ sector_data_offset + 1 ],
344
0
         sector_data[ sector_data_offset + 2 ],
345
0
         sector_lba );
346
347
#if defined( HAVE_DEBUG_OUTPUT ) || defined( HAVE_VERBOSE_OUTPUT )
348
        sector_mode = sector_data[ sector_data_offset + 3 ] & 0x03;
349
#endif
350
#if defined( HAVE_DEBUG_OUTPUT )
351
        if( libcnotify_verbose != 0 )
352
        {
353
          libcnotify_printf(
354
           "%s: sector: %" PRIu32 " MSF\t\t: %02" PRIu8 ":%02" PRIu8 ":%02" PRIu8 " (%" PRIu32 ")\n",
355
           function,
356
           sector_index,
357
           sector_data[ sector_data_offset ],
358
           sector_data[ sector_data_offset + 1 ],
359
           sector_data[ sector_data_offset + 2 ],
360
           sector_lba );
361
362
          libcnotify_printf(
363
           "%s: sector: %" PRIu32 " mode bits\t: 0x%02" PRIx8 "\n",
364
           function,
365
           sector_index,
366
           sector_data[ sector_data_offset + 3 ] );
367
        }
368
#endif
369
#if defined( HAVE_VERBOSE_OUTPUT )
370
        if( sector_lba != sector_index )
371
        {
372
          libcnotify_printf(
373
           "%s: sector MSF (LBA) does not match current.\n",
374
           function );
375
        }
376
        if( ( ( track_type == LIBODRAW_TRACK_TYPE_MODE1_2352 )
377
          &&  ( sector_mode != 1 ) )
378
         || ( ( track_type == LIBODRAW_TRACK_TYPE_MODE2_2352 )
379
          &&  ( sector_mode != 2 ) ) )
380
        {
381
          libcnotify_printf(
382
           "%s: sector mode does not match table of contents.\n",
383
           function );
384
        }
385
#endif
386
0
        sector_data_offset += 4;
387
0
      }
388
0
      else if( bytes_per_sector == 2352 )
389
0
      {
390
0
        sector_data_offset += 16;
391
0
      }
392
0
      if( ( track_type == LIBODRAW_TRACK_TYPE_MODE2_2336 )
393
0
       || ( track_type == LIBODRAW_TRACK_TYPE_MODE2_2352 ) )
394
0
      {
395
0
        if( ( sector_data[ sector_data_offset     ] != sector_data[ sector_data_offset + 4 ] )
396
0
         || ( sector_data[ sector_data_offset + 1 ] != sector_data[ sector_data_offset + 5 ] )
397
0
         || ( sector_data[ sector_data_offset + 2 ] != sector_data[ sector_data_offset + 6 ] )
398
0
         || ( sector_data[ sector_data_offset + 3 ] != sector_data[ sector_data_offset + 7 ] ) )
399
0
        {
400
0
          libcerror_error_set(
401
0
           error,
402
0
           LIBCERROR_ERROR_DOMAIN_INPUT,
403
0
           LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
404
0
           "%s: unsupported or corrupt XA sub-header.",
405
0
           function );
406
407
0
          return( -1 );
408
0
        }
409
0
        if( sector_data[ sector_data_offset + 1 ] >= 32 )
410
0
        {
411
0
          libcerror_error_set(
412
0
           error,
413
0
           LIBCERROR_ERROR_DOMAIN_INPUT,
414
0
           LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
415
0
           "%s: unsupported XA sub-header channel number.",
416
0
           function );
417
418
0
          return( -1 );
419
0
        }
420
#if defined( HAVE_VERBOSE_OUTPUT )
421
        if( libcnotify_verbose != 0 )
422
        {
423
          if( ( sector_data[ sector_data_offset + 2 ] & 0x08 ) != 0 )
424
          {
425
            libcnotify_printf(
426
             "%s: data flag not set in XA sub-header sub-mode flags.\n",
427
             function );
428
          }
429
        }
430
#endif
431
432
/* TODO some writers seem to ignore these flags
433
        if( ( sector_data[ sector_data_offset + 2 ] & 0x08 ) != 0 )
434
        {
435
          libcerror_error_set(
436
           error,
437
           LIBCERROR_ERROR_DOMAIN_INPUT,
438
           LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
439
           "%s: unsupported XA sub-header sub-mode flags - data flag not set.",
440
           function );
441
442
          return( -1 );
443
        }
444
*/
445
0
        sector_data_offset += 8;
446
0
      }
447
0
    }
448
0
    else if( io_handle->bytes_per_sector == 2352 )
449
0
    {
450
0
      if( sector_offset == 0 )
451
0
      {
452
/* TODO what about run-out and lead-out data (have argument indicate non-track data) */
453
0
        if( ( io_handle->mode == 1 )
454
0
         || ( io_handle->mode == 2 ) )
455
0
        {
456
0
          read_size = 12;
457
458
0
          if( ( read_size + buffer_offset ) > buffer_size )
459
0
          {
460
0
            read_size = buffer_size - buffer_offset;
461
0
          }
462
0
          if( memory_copy(
463
0
               &( buffer[ buffer_offset ] ),
464
0
               libodraw_sector_synchronisation_data,
465
0
               read_size ) != 0 )
466
0
          {
467
0
            libcerror_error_set(
468
0
             error,
469
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
470
0
             LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
471
0
             "%s: unsupported copy sector synchronisation data to buffer.",
472
0
             function );
473
474
0
            return( -1 );
475
0
          }
476
0
          buffer_offset += read_size;
477
478
0
          if( buffer_offset >= buffer_size )
479
0
          {
480
0
            break;
481
0
          }
482
/* TODO set MSF requires current sector */
483
0
          buffer[ buffer_offset++ ] = 0;
484
485
0
          if( buffer_offset >= buffer_size )
486
0
          {
487
0
            break;
488
0
          }
489
0
          buffer[ buffer_offset++ ] = 0;
490
491
0
          if( buffer_offset >= buffer_size )
492
0
          {
493
0
            break;
494
0
          }
495
0
          buffer[ buffer_offset++ ] = 0;
496
497
0
          if( buffer_offset >= buffer_size )
498
0
          {
499
0
            break;
500
0
          }
501
0
          if( io_handle->mode == 1 )
502
0
          {
503
0
            buffer[ buffer_offset++ ] = 1;
504
0
          }
505
0
          else if ( io_handle->mode == 2 )
506
0
          {
507
0
            buffer[ buffer_offset++ ] = 2;
508
0
          }
509
0
          if( buffer_offset >= buffer_size )
510
0
          {
511
0
            break;
512
0
          }
513
0
        }
514
0
        else
515
0
        {
516
0
          read_size = 16;
517
518
0
          if( ( read_size + buffer_offset ) > buffer_size )
519
0
          {
520
0
            read_size = buffer_size - buffer_offset;
521
0
          }
522
0
          if( memory_set(
523
0
               &( buffer[ buffer_offset ] ),
524
0
               0,
525
0
               read_size ) == NULL )
526
0
          {
527
0
            libcerror_error_set(
528
0
             error,
529
0
             LIBCERROR_ERROR_DOMAIN_MEMORY,
530
0
             LIBCERROR_MEMORY_ERROR_SET_FAILED,
531
0
             "%s: unable to set sector data in buffer.",
532
0
             function );
533
534
0
            return( -1 );
535
0
          }
536
0
          buffer_offset += read_size;
537
538
0
          if( buffer_offset >= buffer_size )
539
0
          {
540
0
            break;
541
0
          }
542
0
        }
543
0
        if( io_handle->mode == 2 )
544
0
        {
545
/* TODO what about XA sub-header */
546
0
        }
547
0
      }
548
0
    }
549
0
    read_size = io_handle->bytes_per_sector;
550
551
0
    if( sector_offset != 0 )
552
0
    {
553
0
      sector_data_offset += sector_offset;
554
0
      read_size          -= (size_t) sector_offset;
555
0
      sector_offset       = 0;
556
0
    }
557
0
    if( ( read_size + buffer_offset ) > buffer_size )
558
0
    {
559
0
      read_size = buffer_size - buffer_offset;
560
0
    }
561
0
    if( ( track_type == LIBODRAW_TRACK_TYPE_AUDIO )
562
0
     && ( io_handle->bytes_per_sector != 2352 ) )
563
0
    {
564
      /* If the sector size is not 2352 just return 0 bytes
565
       * for audio data
566
       */
567
0
      if( memory_set(
568
0
           &( buffer[ buffer_offset ] ),
569
0
           0,
570
0
           read_size ) == NULL )
571
0
      {
572
0
        libcerror_error_set(
573
0
         error,
574
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
575
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
576
0
         "%s: unable to set sector data to buffer.",
577
0
         function );
578
579
0
        return( -1 );
580
0
      }
581
0
    }
582
0
    else
583
0
    {
584
0
      if( memory_copy(
585
0
           &( buffer[ buffer_offset ] ),
586
0
           &( sector_data[ sector_data_offset ] ),
587
0
           read_size ) == NULL )
588
0
      {
589
0
        libcerror_error_set(
590
0
         error,
591
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
592
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
593
0
         "%s: unable to copy sector data to buffer.",
594
0
         function );
595
596
0
        return( -1 );
597
0
      }
598
0
    }
599
0
    buffer_offset      += read_size;
600
0
    sector_data_offset += read_size;
601
602
0
    if( buffer_offset >= buffer_size )
603
0
    {
604
0
      break;
605
0
    }
606
0
    if( io_handle->bytes_per_sector == 2048 )
607
0
    {
608
0
      if( track_type == LIBODRAW_TRACK_TYPE_MODE1_2352 )
609
0
      {
610
/* TODO calculate checksum, what about read errors ?*/
611
0
        sector_data_offset += 4;
612
613
/* TODO check padding */
614
0
        sector_data_offset += 8;
615
616
/* TODO check ECC data if necessary, what about read errors ? */
617
0
        sector_data_offset += 276;
618
0
      }
619
0
      else if( ( track_type == LIBODRAW_TRACK_TYPE_MODE2_2336 )
620
0
            || ( track_type == LIBODRAW_TRACK_TYPE_MODE2_2352 ) )
621
0
      {
622
/* TODO calculate checksum, what about read errors ?*/
623
0
        sector_data_offset += 4;
624
625
/* TODO check ECC data if necessary, what about read errors ? */
626
0
        sector_data_offset += 276;
627
0
      }
628
0
      else if( bytes_per_sector == 2352 )
629
0
      {
630
0
        sector_data_offset += 288;
631
0
      }
632
0
    }
633
0
    else if( io_handle->bytes_per_sector == 2352 )
634
0
    {
635
/* TODO what about run-out and lead-out data (have argument indicate non-track data) */
636
0
      if( ( io_handle->mode == 1 )
637
0
       || ( io_handle->mode == 2 ) )
638
0
      {
639
0
        read_size = 4;
640
641
0
        if( ( read_size + buffer_offset ) > buffer_size )
642
0
        {
643
0
          read_size = buffer_size - buffer_offset;
644
0
        }
645
/* TODO determine missing data instead of 0 fill */
646
0
        if( memory_set(
647
0
             &( buffer[ buffer_offset ] ),
648
0
             0,
649
0
             read_size ) == NULL )
650
0
        {
651
0
          libcerror_error_set(
652
0
           error,
653
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
654
0
           LIBCERROR_MEMORY_ERROR_SET_FAILED,
655
0
           "%s: unable to set sector checksum in buffer.",
656
0
           function );
657
658
0
          return( -1 );
659
0
        }
660
0
        buffer_offset += read_size;
661
662
0
        if( buffer_offset >= buffer_size )
663
0
        {
664
0
          break;
665
0
        }
666
0
      }
667
0
      if( io_handle->mode == 1 )
668
0
      {
669
0
        read_size = 8;
670
671
0
        if( ( read_size + buffer_offset ) > buffer_size )
672
0
        {
673
0
          read_size = buffer_size - buffer_offset;
674
0
        }
675
0
        if( memory_set(
676
0
             &( buffer[ buffer_offset ] ),
677
0
             0,
678
0
             read_size ) == NULL )
679
0
        {
680
0
          libcerror_error_set(
681
0
           error,
682
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
683
0
           LIBCERROR_MEMORY_ERROR_SET_FAILED,
684
0
           "%s: unable to set sector reserved in buffer.",
685
0
           function );
686
687
0
          return( -1 );
688
0
        }
689
0
        buffer_offset += read_size;
690
691
0
        if( buffer_offset >= buffer_size )
692
0
        {
693
0
          break;
694
0
        }
695
0
      }
696
0
      if( ( io_handle->mode == 1 )
697
0
       || ( io_handle->mode == 2 ) )
698
0
      {
699
0
        read_size = 276;
700
701
0
        if( ( read_size + buffer_offset ) > buffer_size )
702
0
        {
703
0
          read_size = buffer_size - buffer_offset;
704
0
        }
705
/* TODO determine missing data instead of 0 fill */
706
0
        if( memory_set(
707
0
             &( buffer[ buffer_offset ] ),
708
0
             0,
709
0
             read_size ) == NULL )
710
0
        {
711
0
          libcerror_error_set(
712
0
           error,
713
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
714
0
           LIBCERROR_MEMORY_ERROR_SET_FAILED,
715
0
           "%s: unable to set sector error correction data in buffer.",
716
0
           function );
717
718
0
          return( -1 );
719
0
        }
720
0
        buffer_offset += read_size;
721
722
0
        if( buffer_offset >= buffer_size )
723
0
        {
724
0
          break;
725
0
        }
726
0
      }
727
0
      else
728
0
      {
729
0
        read_size = 288;
730
731
0
        if( ( read_size + buffer_offset ) > buffer_size )
732
0
        {
733
0
          read_size = buffer_size - buffer_offset;
734
0
        }
735
0
        if( memory_set(
736
0
             &( buffer[ buffer_offset ] ),
737
0
             0,
738
0
             read_size ) == NULL )
739
0
        {
740
0
          libcerror_error_set(
741
0
           error,
742
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
743
0
           LIBCERROR_MEMORY_ERROR_SET_FAILED,
744
0
           "%s: unable to set sector data in buffer.",
745
0
           function );
746
747
0
          return( -1 );
748
0
        }
749
0
        buffer_offset += read_size;
750
751
0
        if( buffer_offset >= buffer_size )
752
0
        {
753
0
          break;
754
0
        }
755
0
      }
756
0
    }
757
0
    sector_index++;
758
0
  }
759
0
  return( (ssize_t) buffer_offset );
760
0
}
761