Coverage Report

Created: 2025-10-14 07:00

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-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 "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.16k
{
50
3.16k
  static char *function = "libregf_hive_bin_initialize";
51
52
3.16k
  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.16k
  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.16k
  *hive_bin = memory_allocate_structure(
75
3.16k
               libregf_hive_bin_t );
76
77
3.16k
  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.16k
  if( memory_set(
89
3.16k
       *hive_bin,
90
3.16k
       0,
91
3.16k
       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.16k
  if( libcdata_array_initialize(
108
3.16k
       &( ( *hive_bin )->cells_array ),
109
3.16k
       0,
110
3.16k
       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.16k
  ( *hive_bin )->offset = offset;
122
3.16k
  ( *hive_bin )->size   = size;
123
124
3.16k
  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.16k
}
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.16k
{
144
3.16k
  static char *function = "libregf_hive_bin_free";
145
3.16k
  int result            = 1;
146
147
3.16k
  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.16k
  if( *hive_bin != NULL )
159
3.16k
  {
160
3.16k
    if( libcdata_array_free(
161
3.16k
         &( ( *hive_bin )->cells_array ),
162
3.16k
         (int (*)(intptr_t **, libcerror_error_t **)) &libregf_hive_bin_cell_free,
163
3.16k
         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.16k
    if( ( *hive_bin )->data != NULL )
175
2.53k
    {
176
2.53k
      memory_free(
177
2.53k
       ( *hive_bin )->data );
178
2.53k
    }
179
3.16k
    memory_free(
180
3.16k
     *hive_bin );
181
182
3.16k
    *hive_bin = NULL;
183
3.16k
  }
184
3.16k
  return( result );
185
3.16k
}
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
2.81k
{
196
2.81k
  libregf_hive_bin_cell_t *hive_bin_cell = NULL;
197
2.81k
  static char *function                  = "libregf_hive_bin_read_cells_data";
198
2.81k
  size_t data_offset                     = 0;
199
2.81k
  uint32_t cell_size                     = 0;
200
2.81k
  uint32_t file_offset                   = 0;
201
2.81k
  uint8_t flags                          = 0;
202
2.81k
  int cell_index                         = 0;
203
2.81k
  int entry_index                        = 0;
204
205
2.81k
  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
2.81k
  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
2.81k
  if( ( data_size < 4 )
228
2.81k
   || ( data_size > (size_t) SSIZE_MAX ) )
229
4
  {
230
4
    libcerror_error_set(
231
4
     error,
232
4
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
233
4
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
234
4
     "%s: invalid data size value out of bounds.",
235
4
     function );
236
237
4
    return( -1 );
238
4
  }
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
2.81k
  file_offset = hive_bin->offset + sizeof( regf_hive_bin_header_t );
253
254
95.5k
  while( data_offset < data_size )
255
93.0k
  {
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
93.0k
    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
93.0k
    byte_stream_copy_to_uint32_little_endian(
278
93.0k
     &( data[ data_offset ] ),
279
93.0k
     cell_size );
280
281
93.0k
    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
93.0k
    flags = 0;
295
296
93.0k
    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
93.0k
    if( (int32_t) cell_size < 0 )
308
90.8k
    {
309
90.8k
      cell_size = (uint32_t) ( -1 * (int32_t) cell_size );
310
90.8k
    }
311
2.20k
    else
312
2.20k
    {
313
2.20k
      flags |= LIBREGF_HIVE_BIN_CELL_FLAG_UNALLOCATED;
314
2.20k
    }
315
93.0k
    if( cell_size < 4 )
316
26
    {
317
26
      libcerror_error_set(
318
26
       error,
319
26
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
320
26
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
321
26
       "%s: invalid cell size value out of bounds.",
322
26
       function );
323
324
26
      goto on_error;
325
26
    }
326
92.9k
    if( ( cell_size % 8 ) != 0 )
327
93
    {
328
93
      libcerror_error_set(
329
93
       error,
330
93
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
331
93
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
332
93
       "%s: invalid cell size value should be multitude of 8.",
333
93
       function );
334
335
93
      goto on_error;
336
93
    }
337
    /* Remove the size of the cell size value
338
     */
339
92.9k
    cell_size -= 4;
340
341
92.9k
    if( cell_size > ( data_size - data_offset ) )
342
149
    {
343
149
      libcerror_error_set(
344
149
       error,
345
149
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
346
149
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
347
149
       "%s: invalid cell size value exceeds hive bin size.",
348
149
       function );
349
350
149
      goto on_error;
351
149
    }
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
92.7k
    if( libregf_hive_bin_cell_initialize(
366
92.7k
         &hive_bin_cell,
367
92.7k
         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
92.7k
    hive_bin_cell->offset = (uint32_t) file_offset;
379
92.7k
    hive_bin_cell->data   = &( data[ data_offset ] );
380
92.7k
    hive_bin_cell->size   = cell_size;
381
92.7k
    hive_bin_cell->flags |= flags;
382
383
92.7k
    data_offset += cell_size;
384
92.7k
    file_offset += 4 + cell_size;
385
386
92.7k
    if( libcdata_array_append_entry(
387
92.7k
         hive_bin->cells_array,
388
92.7k
         &entry_index,
389
92.7k
         (intptr_t *) hive_bin_cell,
390
92.7k
         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
92.7k
    hive_bin_cell = NULL;
403
404
92.7k
    cell_index++;
405
92.7k
  }
406
/* TODO check cell offset == bin size */
407
408
2.53k
  return( 1 );
409
410
278
on_error:
411
278
  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
278
  return( -1 );
419
2.81k
}
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.16k
{
429
3.16k
  static char *function = "libregf_hive_bin_read_cells_file_io_handle";
430
3.16k
  ssize_t read_count    = 0;
431
432
3.16k
  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.16k
  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.16k
  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.16k
  if( ( hive_bin->size == 0 )
466
3.16k
   || ( hive_bin->size > (uint32_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
467
184
  {
468
184
    libcerror_error_set(
469
184
     error,
470
184
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
471
184
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
472
184
     "%s: invalid hive bin - size value out of bounds.",
473
184
     function );
474
475
184
    return( -1 );
476
184
  }
477
2.98k
  hive_bin->data_size = (size_t) hive_bin->size - sizeof( regf_hive_bin_header_t );
478
479
2.98k
  hive_bin->data = (uint8_t *) memory_allocate(
480
2.98k
                                sizeof( uint8_t ) * hive_bin->data_size );
481
  
482
2.98k
  if( hive_bin->data == NULL )
483
60
  {
484
60
    libcerror_error_set(
485
60
     error,
486
60
     LIBCERROR_ERROR_DOMAIN_MEMORY,
487
60
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
488
60
     "%s: unable to create hive cells data.",
489
60
     function );
490
491
60
    goto on_error;
492
60
  }
493
2.92k
  read_count = libbfio_handle_read_buffer(
494
2.92k
                file_io_handle,
495
2.92k
                hive_bin->data,
496
2.92k
                hive_bin->data_size,
497
2.92k
                error );
498
499
2.92k
  if( read_count != (ssize_t) hive_bin->data_size )
500
106
  {
501
106
    libcerror_error_set(
502
106
     error,
503
106
     LIBCERROR_ERROR_DOMAIN_IO,
504
106
     LIBCERROR_IO_ERROR_READ_FAILED,
505
106
     "%s: unable to read hive bin cells data.",
506
106
     function );
507
508
106
    goto on_error;
509
106
  }
510
2.81k
  if( libregf_hive_bin_read_cells_data(
511
2.81k
       hive_bin,
512
2.81k
       hive_bin->data,
513
2.81k
       hive_bin->data_size,
514
2.81k
       error ) != 1 )
515
282
  {
516
282
    libcerror_error_set(
517
282
     error,
518
282
     LIBCERROR_ERROR_DOMAIN_IO,
519
282
     LIBCERROR_IO_ERROR_READ_FAILED,
520
282
     "%s: unable to read hive bin cells.",
521
282
     function );
522
523
282
    goto on_error;
524
282
  }
525
2.53k
  return( 1 );
526
527
448
on_error:
528
448
  if( hive_bin->data != NULL )
529
388
  {
530
388
    memory_free(
531
388
     hive_bin->data );
532
533
388
    hive_bin->data = NULL;
534
388
  }
535
448
  hive_bin->data_size = 0;
536
537
448
  return( -1 );
538
2.81k
}
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
20.1k
{
653
20.1k
  static char *function = "libregf_hive_bin_get_cell_at_offset";
654
20.1k
  int entry_index       = 0;
655
20.1k
  int number_of_entries = 0;
656
657
20.1k
  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
20.1k
  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
20.1k
  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
20.1k
  if( libcdata_array_get_number_of_entries(
691
20.1k
       hive_bin->cells_array,
692
20.1k
       &number_of_entries,
693
20.1k
       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
20.1k
  for( entry_index = 0;
705
112k
       entry_index < number_of_entries;
706
92.1k
       entry_index++ )
707
112k
  {
708
112k
    if( libcdata_array_get_entry_by_index(
709
112k
         hive_bin->cells_array,
710
112k
         entry_index,
711
112k
         (intptr_t **) hive_bin_cell,
712
112k
         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
112k
    if( ( *hive_bin_cell )->offset == cell_offset )
725
20.0k
    {
726
20.0k
      return( 1 );
727
20.0k
    }
728
112k
  }
729
133
  *hive_bin_cell = NULL;
730
731
133
  return( 0 );
732
20.1k
}
733