Coverage Report

Created: 2024-06-12 07:07

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