Coverage Report

Created: 2026-07-10 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libregf/libregf/libregf_hive_bin.c
Line
Count
Source
1
/*
2
 * Hive Bin 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 <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libregf_debug.h"
28
#include "libregf_definitions.h"
29
#include "libregf_hive_bin.h"
30
#include "libregf_hive_bin_cell.h"
31
#include "libregf_hive_bin_header.h"
32
#include "libregf_libbfio.h"
33
#include "libregf_libcdata.h"
34
#include "libregf_libcerror.h"
35
#include "libregf_libcnotify.h"
36
#include "libregf_libfdatetime.h"
37
38
#include "regf_hive_bin.h"
39
40
/* Creates a hive bin
41
 * Make sure the value hive_bin is referencing, is set to NULL
42
 * Returns 1 if successful or -1 on error
43
 */
44
int libregf_hive_bin_initialize(
45
     libregf_hive_bin_t **hive_bin,
46
     uint32_t offset,
47
     uint32_t size,
48
     libcerror_error_t **error )
49
3.40k
{
50
3.40k
  static char *function = "libregf_hive_bin_initialize";
51
52
3.40k
  if( hive_bin == NULL )
53
0
  {
54
0
    libcerror_error_set(
55
0
     error,
56
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
57
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
58
0
     "%s: invalid hive bin.",
59
0
     function );
60
61
0
    return( -1 );
62
0
  }
63
3.40k
  if( *hive_bin != NULL )
64
0
  {
65
0
    libcerror_error_set(
66
0
     error,
67
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
68
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
69
0
     "%s: invalid hive bin value already set.",
70
0
     function );
71
72
0
    return( -1 );
73
0
  }
74
3.40k
  *hive_bin = memory_allocate_structure(
75
3.40k
               libregf_hive_bin_t );
76
77
3.40k
  if( *hive_bin == NULL )
78
0
  {
79
0
    libcerror_error_set(
80
0
     error,
81
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
82
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
83
0
     "%s: unable to create hive bin.",
84
0
     function );
85
86
0
    goto on_error;
87
0
  }
88
3.40k
  if( memory_set(
89
3.40k
       *hive_bin,
90
3.40k
       0,
91
3.40k
       sizeof( libregf_hive_bin_t ) ) == NULL )
92
0
  {
93
0
    libcerror_error_set(
94
0
     error,
95
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
96
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
97
0
     "%s: unable to clear hive bin.",
98
0
     function );
99
100
0
    memory_free(
101
0
     *hive_bin );
102
103
0
    *hive_bin = NULL;
104
105
0
    return( -1 );
106
0
  }
107
3.40k
  if( libcdata_array_initialize(
108
3.40k
       &( ( *hive_bin )->cells_array ),
109
3.40k
       0,
110
3.40k
       error ) != 1 )
111
0
  {
112
0
    libcerror_error_set(
113
0
     error,
114
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
115
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
116
0
     "%s: unable to create cells array.",
117
0
     function );
118
119
0
    goto on_error;
120
0
  }
121
3.40k
  ( *hive_bin )->offset = offset;
122
3.40k
  ( *hive_bin )->size   = size;
123
124
3.40k
  return( 1 );
125
126
0
on_error:
127
0
  if( *hive_bin != NULL )
128
0
  {
129
0
    memory_free(
130
0
     *hive_bin );
131
132
0
    *hive_bin = NULL;
133
0
  }
134
0
  return( -1 );
135
3.40k
}
136
137
/* Frees a hive bin
138
 * Returns 1 if successful or -1 on error
139
 */
140
int libregf_hive_bin_free(
141
     libregf_hive_bin_t **hive_bin,
142
     libcerror_error_t **error )
143
3.40k
{
144
3.40k
  static char *function = "libregf_hive_bin_free";
145
3.40k
  int result            = 1;
146
147
3.40k
  if( hive_bin == NULL )
148
0
  {
149
0
    libcerror_error_set(
150
0
     error,
151
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
152
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
153
0
     "%s: invalid hive bin.",
154
0
     function );
155
156
0
    return( -1 );
157
0
  }
158
3.40k
  if( *hive_bin != NULL )
159
3.40k
  {
160
3.40k
    if( libcdata_array_free(
161
3.40k
         &( ( *hive_bin )->cells_array ),
162
3.40k
         (int (*)(intptr_t **, libcerror_error_t **)) &libregf_hive_bin_cell_free,
163
3.40k
         error ) != 1 )
164
0
    {
165
0
      libcerror_error_set(
166
0
       error,
167
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
168
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
169
0
       "%s: unable to free the hive bin cells array.",
170
0
       function );
171
172
0
      result = -1;
173
0
    }
174
3.40k
    if( ( *hive_bin )->data != NULL )
175
2.74k
    {
176
2.74k
      memory_free(
177
2.74k
       ( *hive_bin )->data );
178
2.74k
    }
179
3.40k
    memory_free(
180
3.40k
     *hive_bin );
181
182
3.40k
    *hive_bin = NULL;
183
3.40k
  }
184
3.40k
  return( result );
185
3.40k
}
186
187
/* Reads a hive bin and determines its cells
188
 * Returns 1 if successful or -1 on error
189
 */
190
int libregf_hive_bin_read_cells_data(
191
     libregf_hive_bin_t *hive_bin,
192
     const uint8_t *data,
193
     size_t data_size,
194
     libcerror_error_t **error )
195
3.02k
{
196
3.02k
  libregf_hive_bin_cell_t *hive_bin_cell = NULL;
197
3.02k
  static char *function                  = "libregf_hive_bin_read_cells_data";
198
3.02k
  size_t data_offset                     = 0;
199
3.02k
  uint32_t cell_size                     = 0;
200
3.02k
  uint32_t file_offset                   = 0;
201
3.02k
  uint8_t flags                          = 0;
202
3.02k
  int cell_index                         = 0;
203
3.02k
  int entry_index                        = 0;
204
205
3.02k
  if( hive_bin == NULL )
206
0
  {
207
0
    libcerror_error_set(
208
0
     error,
209
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
210
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
211
0
     "%s: invalid hive bin.",
212
0
     function );
213
214
0
    return( -1 );
215
0
  }
216
3.02k
  if( data == NULL )
217
0
  {
218
0
    libcerror_error_set(
219
0
     error,
220
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
221
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
222
0
     "%s: invalid data.",
223
0
     function );
224
225
0
    return( -1 );
226
0
  }
227
3.02k
  if( ( data_size < 4 )
228
3.02k
   || ( data_size > (size_t) SSIZE_MAX ) )
229
3
  {
230
3
    libcerror_error_set(
231
3
     error,
232
3
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
233
3
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
234
3
     "%s: invalid data size value out of bounds.",
235
3
     function );
236
237
3
    return( -1 );
238
3
  }
239
#if defined( HAVE_DEBUG_OUTPUT )
240
  if( libcnotify_verbose != 0 )
241
  {
242
    libcnotify_printf(
243
     "%s: hive bin cells:\n",
244
     function );
245
    libcnotify_print_data(
246
     data,
247
     data_size,
248
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
249
  }
250
#endif
251
/* TODO empty cells array */
252
3.02k
  file_offset = hive_bin->offset + sizeof( regf_hive_bin_header_t );
253
254
103k
  while( data_offset < data_size )
255
100k
  {
256
#if defined( HAVE_DEBUG_OUTPUT )
257
    if( libcnotify_verbose != 0 )
258
    {
259
      libcnotify_printf(
260
       "%s: hive bin cell: %03d offset\t\t: 0x%08" PRIx32 "\n",
261
       function,
262
       cell_index,
263
       file_offset );
264
    }
265
#endif
266
100k
    if( data_offset >= ( data_size - 4 ) )
267
7
    {
268
7
      libcerror_error_set(
269
7
       error,
270
7
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
271
7
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
272
7
       "%s: invalid cell size value exceeds hive bin size.",
273
7
       function );
274
275
7
      goto on_error;
276
7
    }
277
100k
    byte_stream_copy_to_uint32_little_endian(
278
100k
     &( data[ data_offset ] ),
279
100k
     cell_size );
280
281
100k
    data_offset += 4;
282
283
#if defined( HAVE_DEBUG_OUTPUT )
284
    if( libcnotify_verbose != 0 )
285
    {
286
      libcnotify_printf(
287
       "%s: hive bin cell: %03d size\t\t: 0x%08" PRIx32 " (%" PRIi32 ")\n",
288
       function,
289
       cell_index,
290
       cell_size,
291
       (int32_t) cell_size );
292
    }
293
#endif
294
100k
    flags = 0;
295
296
100k
    if( cell_size == 0x80000000UL )
297
3
    {
298
3
      libcerror_error_set(
299
3
       error,
300
3
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
301
3
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
302
3
       "%s: invalid cell size value out of bounds.",
303
3
       function );
304
305
3
      goto on_error;
306
3
    }
307
100k
    if( (int32_t) cell_size < 0 )
308
97.9k
    {
309
97.9k
      cell_size = (uint32_t) ( -1 * (int32_t) cell_size );
310
97.9k
    }
311
2.34k
    else
312
2.34k
    {
313
2.34k
      flags |= LIBREGF_HIVE_BIN_CELL_FLAG_UNALLOCATED;
314
2.34k
    }
315
100k
    if( cell_size < 4 )
316
20
    {
317
20
      libcerror_error_set(
318
20
       error,
319
20
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
320
20
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
321
20
       "%s: invalid cell size value out of bounds.",
322
20
       function );
323
324
20
      goto on_error;
325
20
    }
326
100k
    if( ( cell_size % 8 ) != 0 )
327
97
    {
328
97
      libcerror_error_set(
329
97
       error,
330
97
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
331
97
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
332
97
       "%s: invalid cell size value should be multitude of 8.",
333
97
       function );
334
335
97
      goto on_error;
336
97
    }
337
    /* Remove the size of the cell size value
338
     */
339
100k
    cell_size -= 4;
340
341
100k
    if( cell_size > ( data_size - data_offset ) )
342
154
    {
343
154
      libcerror_error_set(
344
154
       error,
345
154
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
346
154
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
347
154
       "%s: invalid cell size value exceeds hive bin size.",
348
154
       function );
349
350
154
      goto on_error;
351
154
    }
352
#if defined( HAVE_DEBUG_OUTPUT )
353
    if( libcnotify_verbose != 0 )
354
    {
355
      libcnotify_printf(
356
       "%s: hive bin cell: %03d data:\n",
357
       function,
358
       cell_index );
359
      libcnotify_print_data(
360
       &( data[ data_offset ] ),
361
       cell_size,
362
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
363
    }
364
#endif
365
100k
    if( libregf_hive_bin_cell_initialize(
366
100k
         &hive_bin_cell,
367
100k
         error ) != 1 )
368
0
    {
369
0
      libcerror_error_set(
370
0
       error,
371
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
372
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
373
0
       "%s: unable to create hive bin cell.",
374
0
       function );
375
376
0
      goto on_error;
377
0
    }
378
100k
    hive_bin_cell->offset = (uint32_t) file_offset;
379
100k
    hive_bin_cell->data   = &( data[ data_offset ] );
380
100k
    hive_bin_cell->size   = cell_size;
381
100k
    hive_bin_cell->flags |= flags;
382
383
100k
    data_offset += cell_size;
384
100k
    file_offset += 4 + cell_size;
385
386
100k
    if( libcdata_array_append_entry(
387
100k
         hive_bin->cells_array,
388
100k
         &entry_index,
389
100k
         (intptr_t *) hive_bin_cell,
390
100k
         error ) != 1 )
391
0
    {
392
0
      libcerror_error_set(
393
0
       error,
394
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
395
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
396
0
       "%s: unable to append hive bin cell: %d.",
397
0
       function,
398
0
       cell_index );
399
400
0
      goto on_error;
401
0
    }
402
100k
    hive_bin_cell = NULL;
403
404
100k
    cell_index++;
405
100k
  }
406
/* TODO check cell offset == bin size */
407
408
2.74k
  return( 1 );
409
410
281
on_error:
411
281
  if( hive_bin_cell != NULL )
412
0
  {
413
0
    libregf_hive_bin_cell_free(
414
0
     &hive_bin_cell,
415
0
     NULL );
416
0
  }
417
/* TODO empty cells array */
418
281
  return( -1 );
419
3.02k
}
420
421
/* Reads a hive bin and determines its cells
422
 * Returns 1 if successful or -1 on error
423
 */
424
int libregf_hive_bin_read_cells_file_io_handle(
425
     libregf_hive_bin_t *hive_bin,
426
     libbfio_handle_t *file_io_handle,
427
     libcerror_error_t **error )
428
3.40k
{
429
3.40k
  static char *function = "libregf_hive_bin_read_cells_file_io_handle";
430
3.40k
  ssize_t read_count    = 0;
431
432
3.40k
  if( hive_bin == NULL )
433
0
  {
434
0
    libcerror_error_set(
435
0
     error,
436
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
437
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
438
0
     "%s: invalid hive bin.",
439
0
     function );
440
441
0
    return( -1 );
442
0
  }
443
3.40k
  if( hive_bin->cells_array == NULL )
444
0
  {
445
0
    libcerror_error_set(
446
0
     error,
447
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
448
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
449
0
     "%s: invalid hive bin - missing cells array.",
450
0
     function );
451
452
0
    return( -1 );
453
0
  }
454
3.40k
  if( hive_bin->data != NULL )
455
0
  {
456
0
    libcerror_error_set(
457
0
     error,
458
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
459
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
460
0
     "%s: invalid hive bin - data already set.",
461
0
     function );
462
463
0
    return( -1 );
464
0
  }
465
3.40k
  if( ( hive_bin->size == 0 )
466
3.40k
   || ( hive_bin->size > (uint32_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
467
186
  {
468
186
    libcerror_error_set(
469
186
     error,
470
186
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
471
186
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
472
186
     "%s: invalid hive bin - size value out of bounds.",
473
186
     function );
474
475
186
    return( -1 );
476
186
  }
477
3.21k
  hive_bin->data_size = (size_t) hive_bin->size - sizeof( regf_hive_bin_header_t );
478
479
3.21k
  hive_bin->data = (uint8_t *) memory_allocate(
480
3.21k
                                sizeof( uint8_t ) * hive_bin->data_size );
481
482
3.21k
  if( hive_bin->data == NULL )
483
75
  {
484
75
    libcerror_error_set(
485
75
     error,
486
75
     LIBCERROR_ERROR_DOMAIN_MEMORY,
487
75
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
488
75
     "%s: unable to create hive cells data.",
489
75
     function );
490
491
75
    goto on_error;
492
75
  }
493
3.14k
  read_count = libbfio_handle_read_buffer(
494
3.14k
                file_io_handle,
495
3.14k
                hive_bin->data,
496
3.14k
                hive_bin->data_size,
497
3.14k
                error );
498
499
3.14k
  if( read_count != (ssize_t) hive_bin->data_size )
500
115
  {
501
115
    libcerror_error_set(
502
115
     error,
503
115
     LIBCERROR_ERROR_DOMAIN_IO,
504
115
     LIBCERROR_IO_ERROR_READ_FAILED,
505
115
     "%s: unable to read hive bin cells data.",
506
115
     function );
507
508
115
    goto on_error;
509
115
  }
510
3.02k
  if( libregf_hive_bin_read_cells_data(
511
3.02k
       hive_bin,
512
3.02k
       hive_bin->data,
513
3.02k
       hive_bin->data_size,
514
3.02k
       error ) != 1 )
515
284
  {
516
284
    libcerror_error_set(
517
284
     error,
518
284
     LIBCERROR_ERROR_DOMAIN_IO,
519
284
     LIBCERROR_IO_ERROR_READ_FAILED,
520
284
     "%s: unable to read hive bin cells.",
521
284
     function );
522
523
284
    goto on_error;
524
284
  }
525
2.74k
  return( 1 );
526
527
474
on_error:
528
474
  if( hive_bin->data != NULL )
529
399
  {
530
399
    memory_free(
531
399
     hive_bin->data );
532
533
399
    hive_bin->data = NULL;
534
399
  }
535
474
  hive_bin->data_size = 0;
536
537
474
  return( -1 );
538
3.02k
}
539
540
/* Retrieves the number of hive bin cells
541
 * Returns 1 if successful or -1 on error
542
 */
543
int libregf_hive_bin_get_number_of_cells(
544
     libregf_hive_bin_t *hive_bin,
545
     uint16_t *number_of_cells,
546
     libcerror_error_t **error )
547
0
{
548
0
  static char *function = "libregf_hive_bin_get_number_of_cells";
549
0
  int number_of_entries = 0;
550
551
0
  if( hive_bin == NULL )
552
0
  {
553
0
    libcerror_error_set(
554
0
     error,
555
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
556
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
557
0
     "%s: invalid hive bin.",
558
0
     function );
559
560
0
    return( -1 );
561
0
  }
562
0
  if( number_of_cells == NULL )
563
0
  {
564
0
    libcerror_error_set(
565
0
     error,
566
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
567
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
568
0
     "%s: invalid number of cells.",
569
0
     function );
570
571
0
    return( -1 );
572
0
  }
573
0
  if( libcdata_array_get_number_of_entries(
574
0
       hive_bin->cells_array,
575
0
       &number_of_entries,
576
0
       error ) != 1 )
577
0
  {
578
0
    libcerror_error_set(
579
0
     error,
580
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
581
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
582
0
     "%s: unable to retrieve number of entries.",
583
0
     function );
584
585
0
    return( -1 );
586
0
  }
587
0
  if( number_of_entries > (int) UINT16_MAX )
588
0
  {
589
0
    libcerror_error_set(
590
0
     error,
591
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
592
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
593
0
     "%s: invalid number of entries value exceeds maximum.",
594
0
     function );
595
596
0
    return( -1 );
597
0
  }
598
0
  *number_of_cells = (uint16_t) number_of_entries;
599
600
0
  return( 1 );
601
0
}
602
603
/* Retrieves the hive bin cell at the index
604
 * Returns 1 if successful or -1 on error
605
 */
606
int libregf_hive_bin_get_cell(
607
     libregf_hive_bin_t *hive_bin,
608
     uint16_t cell_index,
609
     libregf_hive_bin_cell_t **hive_bin_cell,
610
     libcerror_error_t **error )
611
0
{
612
0
  static char *function = "libregf_hive_bin_get_cell";
613
614
0
  if( hive_bin == NULL )
615
0
  {
616
0
    libcerror_error_set(
617
0
     error,
618
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
619
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
620
0
     "%s: invalid hive bin.",
621
0
     function );
622
623
0
    return( -1 );
624
0
  }
625
0
  if( libcdata_array_get_entry_by_index(
626
0
       hive_bin->cells_array,
627
0
       (int) cell_index,
628
0
       (intptr_t **) hive_bin_cell,
629
0
       error ) != 1 )
630
0
  {
631
0
    libcerror_error_set(
632
0
     error,
633
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
634
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
635
0
     "%s: unable to retrieve hive bin cell: %" PRIu16 ".",
636
0
     function,
637
0
     cell_index );
638
639
0
    return( -1 );
640
0
  }
641
0
  return( 1 );
642
0
}
643
644
/* Retrieves the hive bin cell at the offset
645
 * Returns 1 if successful, 0 if not available or -1 on error
646
 */
647
int libregf_hive_bin_get_cell_at_offset(
648
     libregf_hive_bin_t *hive_bin,
649
     uint32_t cell_offset,
650
     libregf_hive_bin_cell_t **hive_bin_cell,
651
     libcerror_error_t **error )
652
34.5k
{
653
34.5k
  static char *function = "libregf_hive_bin_get_cell_at_offset";
654
34.5k
  int entry_index       = 0;
655
34.5k
  int number_of_entries = 0;
656
657
34.5k
  if( hive_bin == NULL )
658
0
  {
659
0
    libcerror_error_set(
660
0
     error,
661
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
662
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
663
0
     "%s: invalid hive bin.",
664
0
     function );
665
666
0
    return( -1 );
667
0
  }
668
34.5k
  if( hive_bin->cells_array == NULL )
669
0
  {
670
0
    libcerror_error_set(
671
0
     error,
672
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
673
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
674
0
     "%s: invalid hive bin - missing cells array.",
675
0
     function );
676
677
0
    return( -1 );
678
0
  }
679
34.5k
  if( hive_bin_cell == NULL )
680
0
  {
681
0
    libcerror_error_set(
682
0
     error,
683
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
684
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
685
0
     "%s: invalid hive bin cell.",
686
0
     function );
687
688
0
    return( -1 );
689
0
  }
690
34.5k
  if( libcdata_array_get_number_of_entries(
691
34.5k
       hive_bin->cells_array,
692
34.5k
       &number_of_entries,
693
34.5k
       error ) != 1 )
694
0
  {
695
0
    libcerror_error_set(
696
0
     error,
697
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
698
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
699
0
     "%s: unable to retrieve the number of hive bin cells.",
700
0
     function );
701
702
0
    return( -1 );
703
0
  }
704
34.5k
  for( entry_index = 0;
705
165k
       entry_index < number_of_entries;
706
130k
       entry_index++ )
707
165k
  {
708
165k
    if( libcdata_array_get_entry_by_index(
709
165k
         hive_bin->cells_array,
710
165k
         entry_index,
711
165k
         (intptr_t **) hive_bin_cell,
712
165k
         error ) != 1 )
713
0
    {
714
0
      libcerror_error_set(
715
0
       error,
716
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
717
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
718
0
       "%s: unable to retrieve hive bin cell: %d.",
719
0
       function,
720
0
       entry_index );
721
722
0
      return( -1 );
723
0
    }
724
165k
    if( ( *hive_bin_cell )->offset == cell_offset )
725
34.4k
    {
726
34.4k
      return( 1 );
727
34.4k
    }
728
165k
  }
729
129
  *hive_bin_cell = NULL;
730
731
129
  return( 0 );
732
34.5k
}
733