Coverage Report

Created: 2026-04-10 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwrc/libwrc/libwrc_resource_item.c
Line
Count
Source
1
/*
2
 * Resource item functions
3
 *
4
 * Copyright (C) 2011-2025, 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 "libwrc_io_handle.h"
27
#include "libwrc_libbfio.h"
28
#include "libwrc_libcdata.h"
29
#include "libwrc_libcerror.h"
30
#include "libwrc_resource_item.h"
31
#include "libwrc_resource_node_entry.h"
32
33
/* Creates a resource item
34
 * Make sure the value resource_item is referencing, is set to NULL
35
 * Returns 1 if successful or -1 on error
36
 */
37
int libwrc_resource_item_initialize(
38
     libwrc_resource_item_t **resource_item,
39
     libwrc_io_handle_t *io_handle,
40
     libbfio_handle_t *file_io_handle,
41
     libcdata_tree_node_t *resource_node,
42
     libcerror_error_t **error )
43
0
{
44
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
45
0
  libwrc_resource_node_entry_t *resource_node_entry       = NULL;
46
0
  static char *function                                   = "libwrc_resource_item_initialize";
47
48
0
  if( resource_item == NULL )
49
0
  {
50
0
    libcerror_error_set(
51
0
     error,
52
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
53
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
54
0
     "%s: invalid resource item.",
55
0
     function );
56
57
0
    return( -1 );
58
0
  }
59
0
  if( *resource_item != NULL )
60
0
  {
61
0
    libcerror_error_set(
62
0
     error,
63
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
64
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
65
0
     "%s: invalid resource item value already set.",
66
0
     function );
67
68
0
    return( -1 );
69
0
  }
70
0
  if( libcdata_tree_node_get_value(
71
0
       resource_node,
72
0
       (intptr_t **) &resource_node_entry,
73
0
       error ) != 1 )
74
0
  {
75
0
    libcerror_error_set(
76
0
     error,
77
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
78
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
79
0
     "%s: unable to retrieve resource node entry.",
80
0
     function );
81
82
0
    goto on_error;
83
0
  }
84
0
  if( resource_node_entry == NULL )
85
0
  {
86
0
    libcerror_error_set(
87
0
     error,
88
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
89
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
90
0
     "%s: invalid resource node entry.",
91
0
     function );
92
93
0
    goto on_error;
94
0
  }
95
0
  internal_resource_item = memory_allocate_structure(
96
0
                            libwrc_internal_resource_item_t );
97
98
0
  if( internal_resource_item == NULL )
99
0
  {
100
0
    libcerror_error_set(
101
0
     error,
102
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
103
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
104
0
     "%s: unable to create resource item.",
105
0
     function );
106
107
0
    goto on_error;
108
0
  }
109
0
  if( memory_set(
110
0
       internal_resource_item,
111
0
       0,
112
0
       sizeof( libwrc_internal_resource_item_t ) ) == NULL )
113
0
  {
114
0
    libcerror_error_set(
115
0
     error,
116
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
117
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
118
0
     "%s: unable to clear resource item.",
119
0
     function );
120
121
0
    memory_free(
122
0
     internal_resource_item );
123
124
0
    return( -1 );
125
0
  }
126
0
  internal_resource_item->io_handle           = io_handle;
127
0
  internal_resource_item->file_io_handle      = file_io_handle;
128
0
  internal_resource_item->resource_node       = resource_node;
129
0
  internal_resource_item->resource_node_entry = resource_node_entry;
130
131
0
  *resource_item = (libwrc_resource_item_t *) internal_resource_item;
132
133
0
  return( 1 );
134
135
0
on_error:
136
0
  if( internal_resource_item != NULL )
137
0
  {
138
0
    memory_free(
139
0
     internal_resource_item );
140
0
  }
141
0
  return( -1 );
142
0
}
143
144
/* Frees a resource item
145
 * Returns 1 if successful or -1 on error
146
 */
147
int libwrc_resource_item_free(
148
     libwrc_resource_item_t **resource_item,
149
     libcerror_error_t **error )
150
0
{
151
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
152
0
  static char *function                                   = "libwrc_resource_item_free";
153
154
0
  if( resource_item == NULL )
155
0
  {
156
0
    libcerror_error_set(
157
0
     error,
158
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
159
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
160
0
     "%s: invalid resource item.",
161
0
     function );
162
163
0
    return( -1 );
164
0
  }
165
0
  if( *resource_item != NULL )
166
0
  {
167
0
    internal_resource_item = (libwrc_internal_resource_item_t *) *resource_item;
168
0
    *resource_item         = NULL;
169
170
0
    memory_free(
171
0
     internal_resource_item );
172
0
  }
173
0
  return( 1 );
174
0
}
175
176
/* Retrieves the resource item identifier
177
 * Returns 1 if successful or -1 on error
178
 */
179
int libwrc_resource_item_get_identifier(
180
     libwrc_resource_item_t *resource_item,
181
     uint32_t *identifier,
182
     libcerror_error_t **error )
183
0
{
184
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
185
0
  static char *function                                   = "libwrc_resource_item_get_identifier";
186
187
0
  if( resource_item == NULL )
188
0
  {
189
0
    libcerror_error_set(
190
0
     error,
191
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
192
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
193
0
     "%s: invalid resource item.",
194
0
     function );
195
196
0
    return( -1 );
197
0
  }
198
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
199
200
0
  if( libwrc_resource_node_entry_get_identifier(
201
0
       internal_resource_item->resource_node_entry,
202
0
       identifier,
203
0
       error ) != 1 )
204
0
  {
205
0
    libcerror_error_set(
206
0
     error,
207
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
208
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
209
0
     "%s: unable to retrieve identifier.",
210
0
     function );
211
212
0
    return( -1 );
213
0
  }
214
0
  return( 1 );
215
0
}
216
217
/* Retrieves the size of the UTF-8 encoded name
218
 * The returned size includes the end of string character
219
 * Returns 1 if successful, 0 if not available or -1 on error
220
 */
221
int libwrc_resource_item_get_utf8_name_size(
222
     libwrc_resource_item_t *resource_item,
223
     size_t *utf8_string_size,
224
     libcerror_error_t **error )
225
0
{
226
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
227
0
  static char *function                                   = "libwrc_resource_item_get_utf8_name_size";
228
0
  int result                                              = 0;
229
230
0
  if( resource_item == NULL )
231
0
  {
232
0
    libcerror_error_set(
233
0
     error,
234
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
235
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
236
0
     "%s: invalid resource item.",
237
0
     function );
238
239
0
    return( -1 );
240
0
  }
241
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
242
243
0
  result = libwrc_resource_node_entry_get_utf8_name_size(
244
0
            internal_resource_item->resource_node_entry,
245
0
            utf8_string_size,
246
0
            error );
247
248
0
  if( result == -1 )
249
0
  {
250
0
    libcerror_error_set(
251
0
     error,
252
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
253
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
254
0
     "%s: unable to retrieve size of UTF-8 name.",
255
0
     function );
256
257
0
    return( -1 );
258
0
  }
259
0
  return( result );
260
0
}
261
262
/* Retrieves the UTF-8 encoded name
263
 * The size should include the end of string character
264
 * Returns 1 if successful, 0 if not available or -1 on error
265
 */
266
int libwrc_resource_item_get_utf8_name(
267
     libwrc_resource_item_t *resource_item,
268
     uint8_t *utf8_string,
269
     size_t utf8_string_size,
270
     libcerror_error_t **error )
271
0
{
272
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
273
0
  static char *function                                   = "libwrc_resource_item_get_utf8_name";
274
0
  int result                                              = 0;
275
276
0
  if( resource_item == NULL )
277
0
  {
278
0
    libcerror_error_set(
279
0
     error,
280
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
281
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
282
0
     "%s: invalid resource item.",
283
0
     function );
284
285
0
    return( -1 );
286
0
  }
287
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
288
289
0
  result = libwrc_resource_node_entry_get_utf8_name(
290
0
            internal_resource_item->resource_node_entry,
291
0
            utf8_string,
292
0
            utf8_string_size,
293
0
            error );
294
295
0
  if( result == -1 )
296
0
  {
297
0
    libcerror_error_set(
298
0
     error,
299
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
300
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
301
0
     "%s: unable to retrieve size of UTF-8 name.",
302
0
     function );
303
304
0
    return( -1 );
305
0
  }
306
0
  return( result );
307
0
}
308
309
/* Retrieves the size of the UTF-16 encoded name
310
 * The returned size includes the end of string character
311
 * Returns 1 if successful, 0 if not available or -1 on error
312
 */
313
int libwrc_resource_item_get_utf16_name_size(
314
     libwrc_resource_item_t *resource_item,
315
     size_t *utf16_string_size,
316
     libcerror_error_t **error )
317
0
{
318
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
319
0
  static char *function                                   = "libwrc_resource_item_get_utf16_name_size";
320
0
  int result                                              = 0;
321
322
0
  if( resource_item == NULL )
323
0
  {
324
0
    libcerror_error_set(
325
0
     error,
326
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
327
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
328
0
     "%s: invalid resource item.",
329
0
     function );
330
331
0
    return( -1 );
332
0
  }
333
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
334
335
0
  result = libwrc_resource_node_entry_get_utf16_name_size(
336
0
            internal_resource_item->resource_node_entry,
337
0
            utf16_string_size,
338
0
            error );
339
340
0
  if( result == -1 )
341
0
  {
342
0
    libcerror_error_set(
343
0
     error,
344
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
345
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
346
0
     "%s: unable to retrieve size of UTF-16 name.",
347
0
     function );
348
349
0
    return( -1 );
350
0
  }
351
0
  return( result );
352
0
}
353
354
/* Retrieves the UTF-16 encoded name
355
 * The size should include the end of string character
356
 * Returns 1 if successful, 0 if not available or -1 on error
357
 */
358
int libwrc_resource_item_get_utf16_name(
359
     libwrc_resource_item_t *resource_item,
360
     uint16_t *utf16_string,
361
     size_t utf16_string_size,
362
     libcerror_error_t **error )
363
0
{
364
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
365
0
  static char *function                                   = "libwrc_resource_item_get_utf16_name";
366
0
  int result                                              = 0;
367
368
0
  if( resource_item == NULL )
369
0
  {
370
0
    libcerror_error_set(
371
0
     error,
372
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
373
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
374
0
     "%s: invalid resource item.",
375
0
     function );
376
377
0
    return( -1 );
378
0
  }
379
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
380
381
0
  result = libwrc_resource_node_entry_get_utf16_name(
382
0
            internal_resource_item->resource_node_entry,
383
0
            utf16_string,
384
0
            utf16_string_size,
385
0
            error );
386
387
0
  if( result == -1 )
388
0
  {
389
0
    libcerror_error_set(
390
0
     error,
391
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
392
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
393
0
     "%s: unable to retrieve size of UTF-16 name.",
394
0
     function );
395
396
0
    return( -1 );
397
0
  }
398
0
  return( result );
399
0
}
400
401
/* Reads resource item data from the current offset into a buffer
402
 * Returns the number of bytes read or -1 on error
403
 */
404
ssize_t libwrc_resource_item_read_buffer(
405
         libwrc_resource_item_t *resource_item,
406
         uint8_t *buffer,
407
         size_t size,
408
         libcerror_error_t **error )
409
0
{
410
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
411
0
  static char *function                                   = "libwrc_resource_item_read_buffer";
412
0
  ssize_t read_count                                      = 0;
413
0
  off64_t data_offset                                     = 0;
414
415
0
  if( resource_item == NULL )
416
0
  {
417
0
    libcerror_error_set(
418
0
     error,
419
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
420
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
421
0
     "%s: invalid resource item.",
422
0
     function );
423
424
0
    return( -1 );
425
0
  }
426
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
427
428
0
  if( internal_resource_item->io_handle == NULL )
429
0
  {
430
0
    libcerror_error_set(
431
0
     error,
432
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
433
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
434
0
     "%s: invalid resource item - missing IO handle.",
435
0
     function );
436
437
0
    return( -1 );
438
0
  }
439
0
  if( internal_resource_item->resource_node_entry == NULL )
440
0
  {
441
0
    libcerror_error_set(
442
0
     error,
443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
444
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
445
0
     "%s: invalid resource item - missing resource node entry.",
446
0
     function );
447
448
0
    return( -1 );
449
0
  }
450
0
  if( internal_resource_item->resource_node_entry->data_descriptor == NULL )
451
0
  {
452
0
    libcerror_error_set(
453
0
     error,
454
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
455
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
456
0
     "%s: invalid resource item - invalid resource node entry - missing data descriptor.",
457
0
     function );
458
459
0
    return( -1 );
460
0
  }
461
0
  if( internal_resource_item->current_offset < 0 )
462
0
  {
463
0
    libcerror_error_set(
464
0
     error,
465
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
466
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
467
0
     "%s: invalid resource item - current offset value out of bounds.",
468
0
     function );
469
470
0
    return( -1 );
471
0
  }
472
0
  if( buffer == NULL )
473
0
  {
474
0
    libcerror_error_set(
475
0
     error,
476
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
477
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
478
0
     "%s: invalid buffer.",
479
0
     function );
480
481
0
    return( -1 );
482
0
  }
483
0
  if( size > (size_t) SSIZE_MAX )
484
0
  {
485
0
    libcerror_error_set(
486
0
     error,
487
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
488
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
489
0
     "%s: invalid size value exceeds maximum.",
490
0
     function );
491
492
0
    return( -1 );
493
0
  }
494
0
  if( internal_resource_item->current_offset >= (off64_t) internal_resource_item->resource_node_entry->data_descriptor->size )
495
0
  {
496
0
    return( 0 );
497
0
  }
498
0
  if( ( size > (size64_t) internal_resource_item->resource_node_entry->data_descriptor->size )
499
0
   || ( (size64_t) internal_resource_item->current_offset > ( (size64_t) internal_resource_item->resource_node_entry->data_descriptor->size - size ) ) )
500
0
  {
501
0
    size = (size_t)( (off64_t) internal_resource_item->resource_node_entry->data_descriptor->size - internal_resource_item->current_offset );
502
0
  }
503
0
  data_offset  = internal_resource_item->resource_node_entry->data_descriptor->virtual_address;
504
0
  data_offset -= internal_resource_item->io_handle->virtual_address;
505
0
  data_offset += internal_resource_item->current_offset;
506
507
0
  read_count = libbfio_handle_read_buffer_at_offset(
508
0
                internal_resource_item->file_io_handle,
509
0
                buffer,
510
0
                size,
511
0
                data_offset,
512
0
                error );
513
514
0
  if( read_count != (ssize_t) size )
515
0
  {
516
0
    libcerror_error_set(
517
0
     error,
518
0
     LIBCERROR_ERROR_DOMAIN_IO,
519
0
     LIBCERROR_IO_ERROR_READ_FAILED,
520
0
     "%s: unable to read resource data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
521
0
     function,
522
0
     data_offset,
523
0
     data_offset );
524
525
0
    return( -1 );
526
0
  }
527
0
  return( read_count );
528
0
}
529
530
/* Reads resource item data a specific offset into a buffer
531
 * Returns the number of bytes read or -1 on error
532
 */
533
ssize_t libwrc_resource_item_read_buffer_at_offset(
534
         libwrc_resource_item_t *resource_item,
535
         uint8_t *buffer,
536
         size_t buffer_size,
537
         off64_t offset,
538
         libcerror_error_t **error )
539
0
{
540
0
  static char *function = "libwrc_resource_item_read_buffer_at_offset";
541
0
  ssize_t read_count    = 0;
542
543
0
  if( libwrc_resource_item_seek_offset(
544
0
       resource_item,
545
0
       offset,
546
0
       SEEK_SET,
547
0
       error ) == -1 )
548
0
  {
549
0
    libcerror_error_set(
550
0
     error,
551
0
     LIBCERROR_ERROR_DOMAIN_IO,
552
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
553
0
     "%s: unable to seek offset.",
554
0
     function );
555
556
0
    return( -1 );
557
0
  }
558
0
  read_count = libwrc_resource_item_read_buffer(
559
0
                resource_item,
560
0
                buffer,
561
0
                buffer_size,
562
0
                error );
563
564
0
  if( read_count < 0 )
565
0
  {
566
0
    libcerror_error_set(
567
0
     error,
568
0
     LIBCERROR_ERROR_DOMAIN_IO,
569
0
     LIBCERROR_IO_ERROR_READ_FAILED,
570
0
     "%s: unable to read buffer.",
571
0
     function );
572
573
0
    return( -1 );
574
0
  }
575
0
  return( read_count );
576
0
}
577
578
/* Seeks a certain offset of the resource item data
579
 * Returns the offset if seek is successful or -1 on error
580
 */
581
off64_t libwrc_resource_item_seek_offset(
582
         libwrc_resource_item_t *resource_item,
583
         off64_t offset,
584
         int whence,
585
         libcerror_error_t **error )
586
0
{
587
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
588
0
  static char *function                                   = "libwrc_resource_item_seek_offset";
589
590
0
  if( resource_item == NULL )
591
0
  {
592
0
    libcerror_error_set(
593
0
     error,
594
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
595
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
596
0
     "%s: invalid resource item.",
597
0
     function );
598
599
0
    return( -1 );
600
0
  }
601
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
602
603
0
  if( internal_resource_item->resource_node_entry == NULL )
604
0
  {
605
0
    libcerror_error_set(
606
0
     error,
607
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
608
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
609
0
     "%s: invalid resource item - missing resource node entry.",
610
0
     function );
611
612
0
    return( -1 );
613
0
  }
614
0
  if( internal_resource_item->resource_node_entry->data_descriptor == NULL )
615
0
  {
616
0
    libcerror_error_set(
617
0
     error,
618
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
619
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
620
0
     "%s: invalid resource item - invalid resource node entry - missing data descriptor.",
621
0
     function );
622
623
0
    return( -1 );
624
0
  }
625
0
  if( internal_resource_item->current_offset < 0 )
626
0
  {
627
0
    libcerror_error_set(
628
0
     error,
629
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
630
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
631
0
     "%s: invalid resource item - current offset value out of bounds.",
632
0
     function );
633
634
0
    return( -1 );
635
0
  }
636
0
  if( ( whence != SEEK_CUR )
637
0
   && ( whence != SEEK_END )
638
0
   && ( whence != SEEK_SET ) )
639
0
  {
640
0
    libcerror_error_set(
641
0
     error,
642
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
643
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
644
0
     "%s: unsupported whence.",
645
0
     function );
646
647
0
    return( -1 );
648
0
  }
649
0
  if( whence == SEEK_CUR )
650
0
  {
651
0
    offset += internal_resource_item->current_offset;
652
0
  }
653
0
  else if( whence == SEEK_END )
654
0
  {
655
0
    offset += internal_resource_item->resource_node_entry->data_descriptor->size;
656
0
  }
657
0
  if( offset < 0 )
658
0
  {
659
0
    libcerror_error_set(
660
0
     error,
661
0
     LIBCERROR_ERROR_DOMAIN_IO,
662
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
663
0
     "%s: unable to seek offset.",
664
0
     function );
665
666
0
    return( -1 );
667
0
  }
668
0
  internal_resource_item->current_offset = offset;
669
670
0
  return( offset );
671
0
}
672
673
/* Retireves the current offset in the resource item data
674
 * Returns 1 if successful or -1 on error
675
 */
676
int libwrc_resource_item_get_offset(
677
     libwrc_resource_item_t *resource_item,
678
     off64_t *offset,
679
     libcerror_error_t **error )
680
0
{
681
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
682
0
  static char *function                                   = "libwrc_resource_item_get_offset";
683
684
0
  if( resource_item == NULL )
685
0
  {
686
0
    libcerror_error_set(
687
0
     error,
688
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
689
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
690
0
     "%s: invalid resource item.",
691
0
     function );
692
693
0
    return( -1 );
694
0
  }
695
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
696
697
0
  if( internal_resource_item->resource_node_entry == NULL )
698
0
  {
699
0
    libcerror_error_set(
700
0
     error,
701
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
702
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
703
0
     "%s: invalid resource item - missing resource node entry.",
704
0
     function );
705
706
0
    return( -1 );
707
0
  }
708
0
  if( internal_resource_item->resource_node_entry->data_descriptor == NULL )
709
0
  {
710
0
    libcerror_error_set(
711
0
     error,
712
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
713
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
714
0
     "%s: invalid resource item - invalid resource node entry - missing data descriptor.",
715
0
     function );
716
717
0
    return( -1 );
718
0
  }
719
0
  if( offset == NULL )
720
0
  {
721
0
    libcerror_error_set(
722
0
     error,
723
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
724
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
725
0
     "%s: invalid offset.",
726
0
     function );
727
728
0
    return( -1 );
729
0
  }
730
0
  *offset = internal_resource_item->current_offset;
731
732
0
  return( 1 );
733
0
}
734
735
/* Retrieves the size of the resource data
736
 * Returns 1 if successful or -1 on error
737
 */
738
int libwrc_resource_item_get_size(
739
     libwrc_resource_item_t *resource_item,
740
     uint32_t *size,
741
     libcerror_error_t **error )
742
0
{
743
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
744
0
  static char *function                                   = "libwrc_resource_item_get_size";
745
0
  uint32_t safe_size                                      = 0;
746
747
0
  if( resource_item == NULL )
748
0
  {
749
0
    libcerror_error_set(
750
0
     error,
751
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
752
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
753
0
     "%s: invalid resource item.",
754
0
     function );
755
756
0
    return( -1 );
757
0
  }
758
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
759
760
0
  if( internal_resource_item->resource_node_entry == NULL )
761
0
  {
762
0
    libcerror_error_set(
763
0
     error,
764
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
765
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
766
0
     "%s: invalid resource item - missing resource node entry.",
767
0
     function );
768
769
0
    return( -1 );
770
0
  }
771
0
  if( size == NULL )
772
0
  {
773
0
    libcerror_error_set(
774
0
     error,
775
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
776
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
777
0
     "%s: invalid size.",
778
0
     function );
779
780
0
    return( -1 );
781
0
  }
782
0
  if( internal_resource_item->resource_node_entry->data_descriptor != NULL )
783
0
  {
784
0
    safe_size = (uint32_t) internal_resource_item->resource_node_entry->data_descriptor->size;
785
0
  }
786
0
  *size = safe_size;
787
788
0
  return( 1 );
789
0
}
790
791
/* Retrieves the number of sub items
792
 * Returns 1 if successful or -1 on error
793
 */
794
int libwrc_resource_item_get_number_of_sub_items(
795
     libwrc_resource_item_t *resource_item,
796
     int *number_of_sub_items,
797
     libcerror_error_t **error )
798
0
{
799
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
800
0
  static char *function                                   = "libwrc_resource_item_get_number_of_sub_items";
801
802
0
  if( resource_item == NULL )
803
0
  {
804
0
    libcerror_error_set(
805
0
     error,
806
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
807
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
808
0
     "%s: invalid resource item.",
809
0
     function );
810
811
0
    return( -1 );
812
0
  }
813
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
814
815
0
  if( libcdata_tree_node_get_number_of_sub_nodes(
816
0
       internal_resource_item->resource_node,
817
0
       number_of_sub_items,
818
0
       error ) != 1 )
819
0
  {
820
0
    libcerror_error_set(
821
0
     error,
822
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
823
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
824
0
     "%s: unable to retrieve number of resource sub nodes.",
825
0
     function );
826
827
0
    return( -1 );
828
0
  }
829
0
  return( 1 );
830
0
}
831
832
/* Retrieves a specific sub item
833
 * Returns 1 if successful or -1 on error
834
 */
835
int libwrc_resource_item_get_sub_item_by_index(
836
     libwrc_resource_item_t *resource_item,
837
     int sub_item_index,
838
     libwrc_resource_item_t **resource_sub_item,
839
     libcerror_error_t **error )
840
0
{
841
0
  libcdata_tree_node_t *resource_sub_node                 = NULL;
842
0
  libwrc_internal_resource_item_t *internal_resource_item = NULL;
843
0
  static char *function                                   = "libwrc_resource_item_get_sub_item_by_index";
844
845
0
  if( resource_item == NULL )
846
0
  {
847
0
    libcerror_error_set(
848
0
     error,
849
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
850
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
851
0
     "%s: invalid resource item.",
852
0
     function );
853
854
0
    return( -1 );
855
0
  }
856
0
  internal_resource_item = (libwrc_internal_resource_item_t *) resource_item;
857
858
0
  if( libcdata_tree_node_get_sub_node_by_index(
859
0
       internal_resource_item->resource_node,
860
0
       sub_item_index,
861
0
       &resource_sub_node,
862
0
       error ) != 1 )
863
0
  {
864
0
    libcerror_error_set(
865
0
     error,
866
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
867
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
868
0
     "%s: unable to retrieve resource sub node: %d.",
869
0
     function,
870
0
     sub_item_index );
871
872
0
    return( -1 );
873
0
  }
874
0
  if( libwrc_resource_item_initialize(
875
0
       resource_sub_item,
876
0
       internal_resource_item->io_handle,
877
0
       internal_resource_item->file_io_handle,
878
0
       resource_sub_node,
879
0
       error ) != 1 )
880
0
  {
881
0
    libcerror_error_set(
882
0
     error,
883
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
884
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
885
0
     "%s: unable to create resource sub item.",
886
0
     function );
887
888
0
    return( -1 );
889
0
  }
890
0
  return( 1 );
891
0
}
892