Coverage Report

Created: 2025-06-13 07:21

/src/libvsbsdl/libvsbsdl/libvsbsdl_disklabel.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * The disklabel functions
3
 *
4
 * Copyright (C) 2023-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libvsbsdl_disklabel.h"
28
#include "libvsbsdl_libbfio.h"
29
#include "libvsbsdl_libcdata.h"
30
#include "libvsbsdl_libcerror.h"
31
#include "libvsbsdl_libcnotify.h"
32
#include "libvsbsdl_partition_entry.h"
33
34
#include "vsbsdl_disklabel.h"
35
#include "vsbsdl_partition_entry.h"
36
37
/* Creates a disklabel
38
 * Make sure the value disklabel is referencing, is set to NULL
39
 * Returns 1 if successful or -1 on error
40
 */
41
int libvsbsdl_disklabel_initialize(
42
     libvsbsdl_disklabel_t **disklabel,
43
     libcerror_error_t **error )
44
283
{
45
283
  static char *function = "libvsbsdl_disklabel_initialize";
46
47
283
  if( disklabel == NULL )
48
0
  {
49
0
    libcerror_error_set(
50
0
     error,
51
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
52
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
53
0
     "%s: invalid disklabel.",
54
0
     function );
55
56
0
    return( -1 );
57
0
  }
58
283
  if( *disklabel != NULL )
59
0
  {
60
0
    libcerror_error_set(
61
0
     error,
62
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
63
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
64
0
     "%s: invalid disklabel value already set.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
283
  *disklabel = memory_allocate_structure(
70
283
                libvsbsdl_disklabel_t );
71
72
283
  if( *disklabel == NULL )
73
0
  {
74
0
    libcerror_error_set(
75
0
     error,
76
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
77
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
78
0
     "%s: unable to create disklabel.",
79
0
     function );
80
81
0
    goto on_error;
82
0
  }
83
283
  if( memory_set(
84
283
       *disklabel,
85
283
       0,
86
283
       sizeof( libvsbsdl_disklabel_t ) ) == NULL )
87
0
  {
88
0
    libcerror_error_set(
89
0
     error,
90
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
91
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
92
0
     "%s: unable to clear disklabel.",
93
0
     function );
94
95
0
    memory_free(
96
0
     *disklabel );
97
98
0
    *disklabel = NULL;
99
100
0
    return( -1 );
101
0
  }
102
283
  if( libcdata_array_initialize(
103
283
       &( ( *disklabel )->partition_entries ),
104
283
       0,
105
283
       error ) != 1 )
106
0
  {
107
0
    libcerror_error_set(
108
0
     error,
109
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
110
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
111
0
     "%s: unable to create partition entries array.",
112
0
     function );
113
114
0
    goto on_error;
115
0
  }
116
283
  return( 1 );
117
118
0
on_error:
119
0
  if( *disklabel != NULL )
120
0
  {
121
0
    memory_free(
122
0
     *disklabel );
123
124
0
    *disklabel = NULL;
125
0
  }
126
0
  return( -1 );
127
283
}
128
129
/* Frees a disklabel
130
 * Returns 1 if successful or -1 on error
131
 */
132
int libvsbsdl_disklabel_free(
133
     libvsbsdl_disklabel_t **disklabel,
134
     libcerror_error_t **error )
135
283
{
136
283
  static char *function = "libvsbsdl_disklabel_free";
137
283
  int result            = 1;
138
139
283
  if( disklabel == NULL )
140
0
  {
141
0
    libcerror_error_set(
142
0
     error,
143
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
144
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
145
0
     "%s: invalid disklabel.",
146
0
     function );
147
148
0
    return( -1 );
149
0
  }
150
283
  if( *disklabel != NULL )
151
283
  {
152
283
    if( libcdata_array_free(
153
283
         &( ( *disklabel )->partition_entries ),
154
283
         (int (*)(intptr_t **, libcerror_error_t **)) &libvsbsdl_partition_entry_free,
155
283
         error ) != 1 )
156
0
    {
157
0
      libcerror_error_set(
158
0
       error,
159
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
160
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
161
0
       "%s: unable to free the partition entries array.",
162
0
       function );
163
164
0
      result = -1;
165
0
    }
166
283
    memory_free(
167
283
     *disklabel );
168
169
283
    *disklabel = NULL;
170
283
  }
171
283
  return( result );
172
283
}
173
174
/* Reads a disklabel
175
 * Returns 1 if successful or -1 on error
176
 */
177
int libvsbsdl_disklabel_read_data(
178
     libvsbsdl_disklabel_t *disklabel,
179
     const uint8_t *data,
180
     size_t data_size,
181
     libcerror_error_t **error )
182
250
{
183
250
  libvsbsdl_partition_entry_t *partition_entry = NULL;
184
250
  static char *function                        = "libvsbsdl_disklabel_read_data";
185
250
  size_t data_offset                           = 0;
186
250
  uint16_t number_of_partition_entries         = 0;
187
250
  uint16_t partition_entry_index               = 0;
188
250
  int entry_index                              = 0;
189
190
#if defined( HAVE_DEBUG_OUTPUT )
191
  uint32_t value_32bit                         = 0;
192
  uint16_t value_16bit                         = 0;
193
#endif
194
195
250
  if( disklabel == NULL )
196
0
  {
197
0
    libcerror_error_set(
198
0
     error,
199
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
200
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
201
0
     "%s: invalid disklabel.",
202
0
     function );
203
204
0
    return( -1 );
205
0
  }
206
250
  if( data == NULL )
207
0
  {
208
0
    libcerror_error_set(
209
0
     error,
210
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
211
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
212
0
     "%s: invalid data.",
213
0
     function );
214
215
0
    return( -1 );
216
0
  }
217
250
  if( ( data_size < sizeof( vsmbr_disklabel_header_t ) )
218
250
   || ( data_size > (size_t) SSIZE_MAX ) )
219
0
  {
220
0
    libcerror_error_set(
221
0
     error,
222
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
223
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
224
0
     "%s: invalid data size value out of bounds.",
225
0
     function );
226
227
0
    return( -1 );
228
0
  }
229
#if defined( HAVE_DEBUG_OUTPUT )
230
  if( libcnotify_verbose != 0 )
231
  {
232
    libcnotify_printf(
233
     "%s: disklabel data:\n",
234
     function );
235
    libcnotify_print_data(
236
     data,
237
     data_size,
238
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
239
  }
240
#endif
241
250
  if( memory_compare(
242
250
       ( (vsmbr_disklabel_header_t *) data )->signature1,
243
250
       "WEV\x82",
244
250
       4 ) != 0 )
245
57
  {
246
57
    libcerror_error_set(
247
57
     error,
248
57
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
249
57
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
250
57
     "%s: invalid signature.",
251
57
     function );
252
253
57
    return( -1 );
254
57
  }
255
193
  if( memory_compare(
256
193
       ( (vsmbr_disklabel_header_t *) data )->signature2,
257
193
       "WEV\x82",
258
193
       4 ) != 0 )
259
14
  {
260
14
    libcerror_error_set(
261
14
     error,
262
14
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
263
14
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
264
14
     "%s: invalid signature.",
265
14
     function );
266
267
14
    return( -1 );
268
14
  }
269
179
  byte_stream_copy_to_uint32_little_endian(
270
179
   ( (vsmbr_disklabel_header_t *) data )->bytes_per_sector,
271
179
   disklabel->bytes_per_sector );
272
273
179
  byte_stream_copy_to_uint16_little_endian(
274
179
   ( (vsmbr_disklabel_header_t *) data )->number_of_partition_entries,
275
179
   number_of_partition_entries );
276
277
#if defined( HAVE_DEBUG_OUTPUT )
278
  if( libcnotify_verbose != 0 )
279
  {
280
    libcnotify_printf(
281
     "%s: signature1\t\t\t\t: %c%c%c\\x%02" PRIx8 "\n",
282
     function,
283
     ( (vsmbr_disklabel_header_t *) data )->signature1[ 0 ],
284
     ( (vsmbr_disklabel_header_t *) data )->signature1[ 1 ],
285
     ( (vsmbr_disklabel_header_t *) data )->signature1[ 2 ],
286
     ( (vsmbr_disklabel_header_t *) data )->signature1[ 3 ] );
287
288
    byte_stream_copy_to_uint16_little_endian(
289
     ( (vsmbr_disklabel_header_t *) data )->drive_type,
290
     value_16bit );
291
    libcnotify_printf(
292
     "%s: drive type\t\t\t\t: %" PRIu16 "\n",
293
     function,
294
     value_16bit );
295
296
    byte_stream_copy_to_uint16_little_endian(
297
     ( (vsmbr_disklabel_header_t *) data )->drive_sub_type,
298
     value_16bit );
299
    libcnotify_printf(
300
     "%s: drive sub type\t\t\t\t: %" PRIu16 "\n",
301
     function,
302
     value_16bit );
303
304
    libcnotify_printf(
305
     "%s: drive type name:\n",
306
     function );
307
    libcnotify_print_data(
308
     ( (vsmbr_disklabel_header_t *) data )->drive_type_name,
309
     16,
310
     0 );
311
312
    libcnotify_printf(
313
     "%s: unknown1:\n",
314
     function );
315
    libcnotify_print_data(
316
     ( (vsmbr_disklabel_header_t *) data )->unknown1,
317
     16,
318
     0 );
319
320
    libcnotify_printf(
321
     "%s: bytes per sector\t\t\t\t: %" PRIu32 "\n",
322
     function,
323
     disklabel->bytes_per_sector );
324
325
    byte_stream_copy_to_uint32_little_endian(
326
     ( (vsmbr_disklabel_header_t *) data )->sectors_per_track,
327
     value_32bit );
328
    libcnotify_printf(
329
     "%s: sectors per track\t\t\t: %" PRIu32 "\n",
330
     function,
331
     value_32bit );
332
333
    byte_stream_copy_to_uint32_little_endian(
334
     ( (vsmbr_disklabel_header_t *) data )->tracks_per_cylinder,
335
     value_32bit );
336
    libcnotify_printf(
337
     "%s: tracks per cylinder\t\t\t: %" PRIu32 "\n",
338
     function,
339
     value_32bit );
340
341
    byte_stream_copy_to_uint32_little_endian(
342
     ( (vsmbr_disklabel_header_t *) data )->cylinders_per_unit,
343
     value_32bit );
344
    libcnotify_printf(
345
     "%s: cylinders per unit\t\t\t: %" PRIu32 "\n",
346
     function,
347
     value_32bit );
348
349
    byte_stream_copy_to_uint32_little_endian(
350
     ( (vsmbr_disklabel_header_t *) data )->sectors_per_cylinder,
351
     value_32bit );
352
    libcnotify_printf(
353
     "%s: sectors per cylinder\t\t\t: %" PRIu32 "\n",
354
     function,
355
     value_32bit );
356
357
    byte_stream_copy_to_uint32_little_endian(
358
     ( (vsmbr_disklabel_header_t *) data )->sectors_per_unit,
359
     value_32bit );
360
    libcnotify_printf(
361
     "%s: sectors per unit\t\t\t\t: %" PRIu32 "\n",
362
     function,
363
     value_32bit );
364
365
    byte_stream_copy_to_uint16_little_endian(
366
     ( (vsmbr_disklabel_header_t *) data )->spare_sectors_per_track,
367
     value_16bit );
368
    libcnotify_printf(
369
     "%s: spare sectors per track\t\t\t: %" PRIu16 "\n",
370
     function,
371
     value_16bit );
372
373
    byte_stream_copy_to_uint16_little_endian(
374
     ( (vsmbr_disklabel_header_t *) data )->spare_sectors_per_cylinder,
375
     value_16bit );
376
    libcnotify_printf(
377
     "%s: spare sectors per cylinder\t\t: %" PRIu16 "\n",
378
     function,
379
     value_16bit );
380
381
    byte_stream_copy_to_uint32_little_endian(
382
     ( (vsmbr_disklabel_header_t *) data )->alternate_sectors_per_unit,
383
     value_32bit );
384
    libcnotify_printf(
385
     "%s: alternate sectors per unit\t\t: %" PRIu32 "\n",
386
     function,
387
     value_32bit );
388
389
    byte_stream_copy_to_uint16_little_endian(
390
     ( (vsmbr_disklabel_header_t *) data )->unknown2,
391
     value_16bit );
392
    libcnotify_printf(
393
     "%s: unknown2\t\t\t\t\t: 0x%04" PRIx16 "\n",
394
     function,
395
     value_16bit );
396
397
    byte_stream_copy_to_uint16_little_endian(
398
     ( (vsmbr_disklabel_header_t *) data )->unknown3,
399
     value_16bit );
400
    libcnotify_printf(
401
     "%s: unknown3\t\t\t\t\t: 0x%04" PRIx16 "\n",
402
     function,
403
     value_16bit );
404
405
    byte_stream_copy_to_uint16_little_endian(
406
     ( (vsmbr_disklabel_header_t *) data )->unknown4,
407
     value_16bit );
408
    libcnotify_printf(
409
     "%s: unknown4\t\t\t\t\t: 0x%04" PRIx16 "\n",
410
     function,
411
     value_16bit );
412
413
    byte_stream_copy_to_uint16_little_endian(
414
     ( (vsmbr_disklabel_header_t *) data )->unknown5,
415
     value_16bit );
416
    libcnotify_printf(
417
     "%s: unknown5\t\t\t\t\t: 0x%04" PRIx16 "\n",
418
     function,
419
     value_16bit );
420
421
    byte_stream_copy_to_uint32_little_endian(
422
     ( (vsmbr_disklabel_header_t *) data )->unknown6,
423
     value_32bit );
424
    libcnotify_printf(
425
     "%s: unknown6\t\t\t\t\t: 0x%08" PRIx32 "\n",
426
     function,
427
     value_32bit );
428
429
    byte_stream_copy_to_uint32_little_endian(
430
     ( (vsmbr_disklabel_header_t *) data )->unknown7,
431
     value_32bit );
432
    libcnotify_printf(
433
     "%s: unknown7\t\t\t\t\t: 0x%08" PRIx32 "\n",
434
     function,
435
     value_32bit );
436
437
    byte_stream_copy_to_uint32_little_endian(
438
     ( (vsmbr_disklabel_header_t *) data )->flags,
439
     value_32bit );
440
    libcnotify_printf(
441
     "%s: flags\t\t\t\t\t: 0x%08" PRIx32 "\n",
442
     function,
443
     value_32bit );
444
445
    libcnotify_printf(
446
     "%s: unknown8:\n",
447
     function );
448
    libcnotify_print_data(
449
     ( (vsmbr_disklabel_header_t *) data )->unknown8,
450
     20,
451
     0 );
452
453
    libcnotify_printf(
454
     "%s: unknown9:\n",
455
     function );
456
    libcnotify_print_data(
457
     ( (vsmbr_disklabel_header_t *) data )->unknown9,
458
     20,
459
     0 );
460
461
    libcnotify_printf(
462
     "%s: signature2\t\t\t\t: %c%c%c\\x%02" PRIx8 "\n",
463
     function,
464
     ( (vsmbr_disklabel_header_t *) data )->signature2[ 0 ],
465
     ( (vsmbr_disklabel_header_t *) data )->signature2[ 1 ],
466
     ( (vsmbr_disklabel_header_t *) data )->signature2[ 2 ],
467
     ( (vsmbr_disklabel_header_t *) data )->signature2[ 3 ] );
468
469
    byte_stream_copy_to_uint16_little_endian(
470
     ( (vsmbr_disklabel_header_t *) data )->checksum,
471
     value_16bit );
472
    libcnotify_printf(
473
     "%s: checksum\t\t\t\t\t: 0x%04" PRIx16 "\n",
474
     function,
475
     value_16bit );
476
477
    libcnotify_printf(
478
     "%s: number of partition entries\t\t: %" PRIu16 "\n",
479
     function,
480
     number_of_partition_entries );
481
482
    byte_stream_copy_to_uint32_little_endian(
483
     ( (vsmbr_disklabel_header_t *) data )->boot_area_size,
484
     value_32bit );
485
    libcnotify_printf(
486
     "%s: boot area size\t\t\t\t: %" PRIu32 "\n",
487
     function,
488
     value_32bit );
489
490
    byte_stream_copy_to_uint32_little_endian(
491
     ( (vsmbr_disklabel_header_t *) data )->maximum_superblock_size,
492
     value_32bit );
493
    libcnotify_printf(
494
     "%s: maximum superblock size\t\t\t: %" PRIu32 "\n",
495
     function,
496
     value_32bit );
497
498
    libcnotify_printf(
499
     "\n" );
500
  }
501
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
502
503
179
  data_offset = sizeof( vsmbr_disklabel_header_t );
504
505
179
  if( ( number_of_partition_entries != 8 )
506
179
   && ( number_of_partition_entries != 16 ) )
507
20
  {
508
20
    libcerror_error_set(
509
20
     error,
510
20
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
511
20
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
512
20
     "%s: unsupported number of partition entries value.",
513
20
     function );
514
515
20
    return( -1 );
516
20
  }
517
159
  if( number_of_partition_entries > ( ( data_size - data_offset ) / sizeof( vsbsdl_partition_entry_t ) ) )
518
0
  {
519
0
    libcerror_error_set(
520
0
     error,
521
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
522
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
523
0
     "%s: invalid number of partition entries value out of bounds.",
524
0
     function );
525
526
0
    return( -1 );
527
0
  }
528
159
  for( partition_entry_index = 0;
529
2.59k
       partition_entry_index < number_of_partition_entries;
530
2.44k
       partition_entry_index++ )
531
2.44k
  {
532
2.44k
    if( libvsbsdl_partition_entry_initialize(
533
2.44k
         &partition_entry,
534
2.44k
         error ) != 1 )
535
0
    {
536
0
      libcerror_error_set(
537
0
       error,
538
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
539
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
540
0
       "%s: unable to create partition entry: %" PRIu16 ".",
541
0
       function,
542
0
       partition_entry_index );
543
544
0
      goto on_error;
545
0
    }
546
2.44k
    partition_entry->index = partition_entry_index;
547
548
2.44k
    if( libvsbsdl_partition_entry_read_data(
549
2.44k
         partition_entry,
550
2.44k
         &( data[ data_offset ] ),
551
2.44k
         sizeof( vsbsdl_partition_entry_t ),
552
2.44k
         error ) != 1 )
553
0
    {
554
0
      libcerror_error_set(
555
0
       error,
556
0
       LIBCERROR_ERROR_DOMAIN_IO,
557
0
       LIBCERROR_IO_ERROR_READ_FAILED,
558
0
       "%s: unable to read partition entry: %" PRIu16 " data.",
559
0
       function,
560
0
       partition_entry_index );
561
562
0
      goto on_error;
563
0
    }
564
2.44k
    if( partition_entry->number_of_sectors == 0 )
565
847
    {
566
847
      if( libvsbsdl_partition_entry_free(
567
847
           &partition_entry,
568
847
           error ) != 1 )
569
0
      {
570
0
        libcerror_error_set(
571
0
         error,
572
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
573
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
574
0
         "%s: unable to free partition entry: %" PRIu16 ".",
575
0
         function,
576
0
         partition_entry_index );
577
578
0
        goto on_error;
579
0
      }
580
847
    }
581
1.59k
    else
582
1.59k
    {
583
1.59k
      if( libcdata_array_append_entry(
584
1.59k
           disklabel->partition_entries,
585
1.59k
           &entry_index,
586
1.59k
           (intptr_t *) partition_entry,
587
1.59k
           error ) != 1 )
588
0
      {
589
0
        libcerror_error_set(
590
0
         error,
591
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
592
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
593
0
         "%s: unable to append partition entry: %" PRIu16 " to array.",
594
0
         function,
595
0
         partition_entry_index );
596
597
0
        goto on_error;
598
0
      }
599
1.59k
      partition_entry->index = partition_entry_index;
600
601
1.59k
      partition_entry = NULL;
602
1.59k
    }
603
2.44k
    data_offset += sizeof( vsbsdl_partition_entry_t );
604
2.44k
  }
605
159
  return( 1 );
606
607
0
on_error:
608
0
  if( partition_entry != NULL )
609
0
  {
610
0
    libvsbsdl_partition_entry_free(
611
0
     &partition_entry,
612
0
     NULL );
613
0
  }
614
0
  libcdata_array_empty(
615
0
   disklabel->partition_entries,
616
0
   (int (*)(intptr_t **, libcerror_error_t **)) &libvsbsdl_partition_entry_free,
617
0
   NULL );
618
619
0
  return( -1 );
620
159
}
621
622
/* Reads a disklabel
623
 * Returns 1 if successful or -1 on error
624
 */
625
int libvsbsdl_disklabel_read_file_io_handle(
626
     libvsbsdl_disklabel_t *disklabel,
627
     libbfio_handle_t *file_io_handle,
628
     off64_t file_offset,
629
     libcerror_error_t **error )
630
283
{
631
283
  uint8_t disklabel_data[ 512 ];
632
633
283
  static char *function = "libvsbsdl_disklabel_read_file_io_handle";
634
283
  ssize_t read_count    = 0;
635
636
283
  if( disklabel == NULL )
637
0
  {
638
0
    libcerror_error_set(
639
0
     error,
640
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
641
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
642
0
     "%s: invalid disklabel.",
643
0
     function );
644
645
0
    return( -1 );
646
0
  }
647
#if defined( HAVE_DEBUG_OUTPUT )
648
  if( libcnotify_verbose != 0 )
649
  {
650
    libcnotify_printf(
651
     "%s: reading disklabel at offset: %" PRIi64 " (0x%08" PRIx64 ").\n",
652
     function,
653
     file_offset,
654
     file_offset );
655
  }
656
#endif
657
283
  read_count = libbfio_handle_read_buffer_at_offset(
658
283
                file_io_handle,
659
283
                disklabel_data,
660
283
                512,
661
283
                file_offset,
662
283
                error );
663
664
283
  if( read_count != (ssize_t) 512 )
665
33
  {
666
33
    libcerror_error_set(
667
33
     error,
668
33
     LIBCERROR_ERROR_DOMAIN_IO,
669
33
     LIBCERROR_IO_ERROR_READ_FAILED,
670
33
     "%s: unable to read disklabel data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
671
33
     function,
672
33
     file_offset,
673
33
     file_offset );
674
675
33
    return( -1 );
676
33
  }
677
250
  if( libvsbsdl_disklabel_read_data(
678
250
       disklabel,
679
250
       disklabel_data,
680
250
       512,
681
250
       error ) != 1 )
682
91
  {
683
91
    libcerror_error_set(
684
91
     error,
685
91
     LIBCERROR_ERROR_DOMAIN_IO,
686
91
     LIBCERROR_IO_ERROR_READ_FAILED,
687
91
     "%s: unable to read disklabel.",
688
91
     function );
689
690
91
    return( -1 );
691
91
  }
692
159
  return( 1 );
693
250
}
694
695
/* Retrieves the bytes per sector
696
 * Returns 1 if successful or -1 on error
697
 */
698
int libvsbsdl_disklabel_get_bytes_per_sector(
699
     libvsbsdl_disklabel_t *disklabel,
700
     uint32_t *bytes_per_sector,
701
     libcerror_error_t **error )
702
159
{
703
159
  static char *function = "libvsbsdl_disklabel_get_bytes_per_sector";
704
705
159
  if( disklabel == NULL )
706
0
  {
707
0
    libcerror_error_set(
708
0
     error,
709
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
710
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
711
0
     "%s: invalid disklabel.",
712
0
     function );
713
714
0
    return( -1 );
715
0
  }
716
159
  if( bytes_per_sector == NULL )
717
0
  {
718
0
    libcerror_error_set(
719
0
     error,
720
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
721
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
722
0
     "%s: invalid bytes per sector.",
723
0
     function );
724
725
0
    return( -1 );
726
0
  }
727
159
  *bytes_per_sector = disklabel->bytes_per_sector;
728
729
159
  return( 1 );
730
159
}
731
732
/* Retrieves the number of partition entries
733
 * Returns 1 if successful or -1 on error
734
 */
735
int libvsbsdl_disklabel_get_number_of_partition_entries(
736
     libvsbsdl_disklabel_t *disklabel,
737
     int *number_of_partition_entries,
738
     libcerror_error_t **error )
739
159
{
740
159
  static char *function = "libvsbsdl_disklabel_get_number_of_partition_entries";
741
742
159
  if( disklabel == NULL )
743
0
  {
744
0
    libcerror_error_set(
745
0
     error,
746
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
747
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
748
0
     "%s: invalid disklabel.",
749
0
     function );
750
751
0
    return( -1 );
752
0
  }
753
159
  if( libcdata_array_get_number_of_entries(
754
159
       disklabel->partition_entries,
755
159
       number_of_partition_entries,
756
159
       error ) != 1 )
757
0
  {
758
0
    libcerror_error_set(
759
0
     error,
760
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
761
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
762
0
     "%s: unable to retrieve number of partition entries from array.",
763
0
     function );
764
765
0
    return( -1 );
766
0
  }
767
159
  return( 1 );
768
159
}
769
770
/* Retrieves a specific partition entry
771
 * Returns 1 if successful or -1 on error
772
 */
773
int libvsbsdl_disklabel_get_partition_entry_by_index(
774
     libvsbsdl_disklabel_t *disklabel,
775
     int partition_entry_index,
776
     libvsbsdl_partition_entry_t **partition_entry,
777
     libcerror_error_t **error )
778
158
{
779
158
  static char *function = "libvsbsdl_disklabel_get_partition_entry_by_index";
780
781
158
  if( disklabel == NULL )
782
0
  {
783
0
    libcerror_error_set(
784
0
     error,
785
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
786
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
787
0
     "%s: invalid disklabel.",
788
0
     function );
789
790
0
    return( -1 );
791
0
  }
792
158
  if( libcdata_array_get_entry_by_index(
793
158
       disklabel->partition_entries,
794
158
       partition_entry_index,
795
158
       (intptr_t **) partition_entry,
796
158
       error ) != 1 )
797
0
  {
798
0
    libcerror_error_set(
799
0
     error,
800
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
801
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
802
0
     "%s: unable to retrieve partition entry: %d from array.",
803
0
     function,
804
0
     partition_entry_index );
805
806
0
    return( -1 );
807
0
  }
808
158
  return( 1 );
809
158
}
810