Coverage Report

Created: 2024-10-02 06:58

/src/libwrc/libwrc/libwrc_resource.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Resource 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 <memory.h>
24
#include <types.h>
25
26
#include "libwrc_definitions.h"
27
#include "libwrc_io_handle.h"
28
#include "libwrc_language_entry.h"
29
#include "libwrc_language_table.h"
30
#include "libwrc_libbfio.h"
31
#include "libwrc_libcdata.h"
32
#include "libwrc_libcerror.h"
33
#include "libwrc_libcnotify.h"
34
#include "libwrc_libfvalue.h"
35
#include "libwrc_libfwnt.h"
36
#include "libwrc_manifest_values.h"
37
#include "libwrc_message_table_values.h"
38
#include "libwrc_mui_values.h"
39
#include "libwrc_resource.h"
40
#include "libwrc_resource_item.h"
41
#include "libwrc_resource_node_entry.h"
42
#include "libwrc_string_values.h"
43
#include "libwrc_version_values.h"
44
45
/* Creates a resource
46
 * Make sure the value resource is referencing, is set to NULL
47
 * Returns 1 if successful or -1 on error
48
 */
49
int libwrc_resource_initialize(
50
     libwrc_resource_t **resource,
51
     libwrc_io_handle_t *io_handle,
52
     libbfio_handle_t *file_io_handle,
53
     libcdata_tree_node_t *resource_node,
54
     libcerror_error_t **error )
55
0
{
56
0
  libwrc_internal_resource_t *internal_resource     = NULL;
57
0
  libwrc_resource_node_entry_t *resource_node_entry = NULL;
58
0
  static char *function                             = "libwrc_resource_initialize";
59
60
0
  if( resource == NULL )
61
0
  {
62
0
    libcerror_error_set(
63
0
     error,
64
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
65
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
66
0
     "%s: invalid resource.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
0
  if( *resource != NULL )
72
0
  {
73
0
    libcerror_error_set(
74
0
     error,
75
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
76
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
77
0
     "%s: invalid resource value already set.",
78
0
     function );
79
80
0
    return( -1 );
81
0
  }
82
0
  if( libcdata_tree_node_get_value(
83
0
       resource_node,
84
0
       (intptr_t **) &resource_node_entry,
85
0
       error ) != 1 )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
90
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
91
0
     "%s: unable to retrieve resource node entry.",
92
0
     function );
93
94
0
    goto on_error;
95
0
  }
96
0
  if( resource_node_entry == NULL )
97
0
  {
98
0
    libcerror_error_set(
99
0
     error,
100
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
101
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
102
0
     "%s: invalid resource node entry.",
103
0
     function );
104
105
0
    goto on_error;
106
0
  }
107
0
  internal_resource = memory_allocate_structure(
108
0
                       libwrc_internal_resource_t );
109
110
0
  if( internal_resource == NULL )
111
0
  {
112
0
    libcerror_error_set(
113
0
     error,
114
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
115
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
116
0
     "%s: unable to create resource.",
117
0
     function );
118
119
0
    goto on_error;
120
0
  }
121
0
  if( memory_set(
122
0
       internal_resource,
123
0
       0,
124
0
       sizeof( libwrc_internal_resource_t ) ) == NULL )
125
0
  {
126
0
    libcerror_error_set(
127
0
     error,
128
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
129
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
130
0
     "%s: unable to clear resource.",
131
0
     function );
132
133
0
    memory_free(
134
0
     internal_resource );
135
136
0
    return( -1 );
137
0
  }
138
0
  internal_resource->io_handle           = io_handle;
139
0
  internal_resource->file_io_handle      = file_io_handle;
140
0
  internal_resource->resource_node       = resource_node;
141
0
  internal_resource->resource_node_entry = resource_node_entry;
142
143
0
  *resource = (libwrc_resource_t *) internal_resource;
144
145
0
  return( 1 );
146
147
0
on_error:
148
0
  if( internal_resource != NULL )
149
0
  {
150
0
    memory_free(
151
0
     internal_resource );
152
0
  }
153
0
  return( -1 );
154
0
}
155
156
/* Frees a resource
157
 * Returns 1 if successful or -1 on error
158
 */
159
int libwrc_resource_free(
160
     libwrc_resource_t **resource,
161
     libcerror_error_t **error )
162
0
{
163
0
  libwrc_internal_resource_t *internal_resource = NULL;
164
0
  static char *function                         = "libwrc_resource_free";
165
0
  int result                                    = 1;
166
167
0
  if( resource == NULL )
168
0
  {
169
0
    libcerror_error_set(
170
0
     error,
171
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
172
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
173
0
     "%s: invalid resource.",
174
0
     function );
175
176
0
    return( -1 );
177
0
  }
178
0
  if( *resource != NULL )
179
0
  {
180
0
    internal_resource = (libwrc_internal_resource_t *) *resource;
181
0
    *resource         = NULL;
182
183
    /* The io_handle, file_io_handle, resource_node and resource_node_entry references are freed elsewhere
184
     */
185
0
    if( internal_resource->value != NULL )
186
0
    {
187
0
      if( internal_resource->free_value != NULL )
188
0
      {
189
0
        if( internal_resource->free_value(
190
0
             &( internal_resource->value ),
191
0
             error ) != 1 )
192
0
        {
193
0
          libcerror_error_set(
194
0
           error,
195
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
196
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
197
0
           "%s: unable to free resource value.",
198
0
           function );
199
200
0
          result = -1;
201
0
        }
202
0
      }
203
0
    }
204
0
    memory_free(
205
0
     internal_resource );
206
0
  }
207
0
  return( result );
208
0
}
209
210
/* Read the values
211
 * Returns 1 if successful or -1 on error
212
 */
213
int libwrc_resource_read_value(
214
     libwrc_internal_resource_t *internal_resource,
215
     libcerror_error_t **error )
216
0
{
217
0
  libcdata_tree_node_t *leaf_node                        = NULL;
218
0
  libcdata_tree_node_t *sub_node                         = NULL;
219
0
  libwrc_data_descriptor_t *data_descriptor              = NULL;
220
0
  libwrc_language_entry_t *existing_language_entry       = NULL;
221
0
  libwrc_language_entry_t *language_entry                = NULL;
222
0
  libwrc_resource_node_entry_t *leaf_resource_node_entry = NULL;
223
0
  libwrc_resource_node_entry_t *sub_resource_node_entry  = NULL;
224
0
  static char *function                                  = "libwrc_resource_read_value";
225
0
  const char *resource_type_string                       = NULL;
226
0
  int entry_index                                        = 0;
227
0
  int leaf_node_index                                    = 0;
228
0
  int number_of_leaf_nodes                               = 0;
229
0
  int number_of_sub_nodes                                = 0;
230
0
  int result                                             = 0;
231
0
  int sub_node_index                                     = 0;
232
233
0
  if( internal_resource == NULL )
234
0
  {
235
0
    libcerror_error_set(
236
0
     error,
237
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
238
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
239
0
     "%s: invalid resource.",
240
0
     function );
241
242
0
    return( -1 );
243
0
  }
244
0
  if( internal_resource->resource_node == NULL )
245
0
  {
246
0
    libcerror_error_set(
247
0
     error,
248
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
249
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
250
0
     "%s: invalid resource - missing resource node.",
251
0
     function );
252
253
0
    return( -1 );
254
0
  }
255
0
  if( internal_resource->resource_node_entry == NULL )
256
0
  {
257
0
    libcerror_error_set(
258
0
     error,
259
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
260
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
261
0
     "%s: invalid resource - missing resource node entry.",
262
0
     function );
263
264
0
    return( -1 );
265
0
  }
266
0
  switch( internal_resource->resource_node_entry->type )
267
0
  {
268
0
    case LIBWRC_RESOURCE_TYPE_STRING_TABLE:
269
0
      resource_type_string = "string";
270
271
0
      result = libwrc_language_table_initialize(
272
0
                (libwrc_language_table_t **) &( internal_resource->value ),
273
0
                error );
274
275
0
      internal_resource->free_value = (int (*)(intptr_t **, libcerror_error_t **)) &libwrc_language_table_free;
276
277
0
      break;
278
279
0
    case LIBWRC_RESOURCE_TYPE_MESSAGE_TABLE:
280
0
      resource_type_string = "message table";
281
282
0
      result = libwrc_language_table_initialize(
283
0
                (libwrc_language_table_t **) &( internal_resource->value ),
284
0
                error );
285
286
0
      internal_resource->free_value = (int (*)(intptr_t **, libcerror_error_t **)) &libwrc_language_table_free;
287
288
0
      break;
289
290
0
    case LIBWRC_RESOURCE_TYPE_MANIFEST:
291
0
      resource_type_string = "manifest";
292
293
0
      result = libwrc_language_table_initialize(
294
0
                (libwrc_language_table_t **) &( internal_resource->value ),
295
0
                error );
296
297
0
      internal_resource->free_value = (int (*)(intptr_t **, libcerror_error_t **)) &libwrc_language_table_free;
298
299
0
      break;
300
301
0
    case LIBWRC_RESOURCE_TYPE_MUI:
302
0
      resource_type_string = "mui";
303
304
0
      result = libwrc_language_table_initialize(
305
0
                (libwrc_language_table_t **) &( internal_resource->value ),
306
0
                error );
307
308
0
      internal_resource->free_value = (int (*)(intptr_t **, libcerror_error_t **)) &libwrc_language_table_free;
309
310
0
      break;
311
312
0
    case LIBWRC_RESOURCE_TYPE_VERSION_INFORMATION:
313
0
      resource_type_string = "version";
314
315
0
      result = libwrc_language_table_initialize(
316
0
                (libwrc_language_table_t **) &( internal_resource->value ),
317
0
                error );
318
319
0
      internal_resource->free_value = (int (*)(intptr_t **, libcerror_error_t **)) &libwrc_language_table_free;
320
321
0
      break;
322
323
0
    default:
324
#if defined( HAVE_DEBUG_OUTPUT )
325
      resource_type_string = "UNKNOWN";
326
327
      result = 1;
328
329
      break;
330
#else
331
0
      libcerror_error_set(
332
0
       error,
333
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
334
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
335
0
       "%s: unsupported resource type: 0x%08" PRIx32 ".",
336
0
       function,
337
0
       internal_resource->resource_node_entry->type );
338
339
0
      goto on_error;
340
0
#endif
341
0
  }
342
0
  if( result != 1 )
343
0
  {
344
0
    libcerror_error_set(
345
0
     error,
346
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
347
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
348
0
     "%s: unable to create %s resource.",
349
0
     function,
350
0
     resource_type_string );
351
352
0
    goto on_error;
353
0
  }
354
0
  if( libcdata_tree_node_get_number_of_sub_nodes(
355
0
       internal_resource->resource_node,
356
0
       &number_of_sub_nodes,
357
0
       error ) != 1 )
358
0
  {
359
0
    libcerror_error_set(
360
0
     error,
361
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
362
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
363
0
     "%s: unable to retrieve number of sub nodes.",
364
0
     function );
365
366
0
    goto on_error;
367
0
  }
368
0
  if( ( internal_resource->resource_node_entry->type == LIBWRC_RESOURCE_TYPE_MESSAGE_TABLE )
369
0
   || ( internal_resource->resource_node_entry->type == LIBWRC_RESOURCE_TYPE_VERSION_INFORMATION )
370
0
   || ( internal_resource->resource_node_entry->type == LIBWRC_RESOURCE_TYPE_MANIFEST )
371
0
   || ( internal_resource->resource_node_entry->type == LIBWRC_RESOURCE_TYPE_MUI ) )
372
0
  {
373
0
    if( number_of_sub_nodes != 1 )
374
0
    {
375
0
      libcerror_error_set(
376
0
       error,
377
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
378
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
379
0
       "%s: unsupported number of sub nodes: %d.",
380
0
       function,
381
0
       number_of_sub_nodes );
382
383
0
      goto on_error;
384
0
    }
385
0
  }
386
0
  for( sub_node_index = 0;
387
0
       sub_node_index < number_of_sub_nodes;
388
0
       sub_node_index++ )
389
0
  {
390
0
    if( libcdata_tree_node_get_sub_node_by_index(
391
0
         internal_resource->resource_node,
392
0
         sub_node_index,
393
0
         &sub_node,
394
0
         error ) != 1 )
395
0
    {
396
0
      libcerror_error_set(
397
0
       error,
398
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
399
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
400
0
       "%s: unable to retrieve sub node: %d.",
401
0
       function,
402
0
       sub_node_index );
403
404
0
      goto on_error;
405
0
    }
406
0
    if( libcdata_tree_node_get_value(
407
0
         sub_node,
408
0
         (intptr_t **) &sub_resource_node_entry,
409
0
         error ) != 1 )
410
0
    {
411
0
      libcerror_error_set(
412
0
       error,
413
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
414
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
415
0
       "%s: unable to retrieve resource sub node: %d entry.",
416
0
       function,
417
0
       sub_node_index );
418
419
0
      goto on_error;
420
0
    }
421
0
    if( sub_resource_node_entry == NULL )
422
0
    {
423
0
      libcerror_error_set(
424
0
       error,
425
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
426
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
427
0
       "%s: invalid resource sub node: %d entry.",
428
0
       function,
429
0
       sub_node_index );
430
431
0
      goto on_error;
432
0
    }
433
0
    if( libcdata_tree_node_get_number_of_sub_nodes(
434
0
         sub_node,
435
0
         &number_of_leaf_nodes,
436
0
         error ) != 1 )
437
0
    {
438
0
      libcerror_error_set(
439
0
       error,
440
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
441
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
442
0
       "%s: unable to retrieve number of leaf nodes.",
443
0
       function );
444
445
0
      goto on_error;
446
0
    }
447
0
    for( leaf_node_index = 0;
448
0
         leaf_node_index < number_of_leaf_nodes;
449
0
         leaf_node_index++ )
450
0
    {
451
0
      if( libcdata_tree_node_get_sub_node_by_index(
452
0
           sub_node,
453
0
           leaf_node_index,
454
0
           &leaf_node,
455
0
           error ) != 1 )
456
0
      {
457
0
        libcerror_error_set(
458
0
         error,
459
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
460
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
461
0
         "%s: unable to retrieve leaf node: %d.",
462
0
         function,
463
0
         leaf_node_index );
464
465
0
        goto on_error;
466
0
      }
467
0
      if( libcdata_tree_node_get_value(
468
0
           leaf_node,
469
0
           (intptr_t **) &leaf_resource_node_entry,
470
0
           error ) != 1 )
471
0
      {
472
0
        libcerror_error_set(
473
0
         error,
474
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
475
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
476
0
         "%s: unable to retrieve resource leaf node: %d entry.",
477
0
         function,
478
0
         leaf_node_index );
479
480
0
        goto on_error;
481
0
      }
482
0
      if( leaf_resource_node_entry == NULL )
483
0
      {
484
0
        libcerror_error_set(
485
0
         error,
486
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
487
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
488
0
         "%s: invalid resource leaf node: %d entry.",
489
0
         function,
490
0
         leaf_node_index );
491
492
0
        goto on_error;
493
0
      }
494
0
      if( leaf_resource_node_entry->data_descriptor == NULL )
495
0
      {
496
0
        libcerror_error_set(
497
0
         error,
498
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
499
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
500
0
         "%s: invalid resource leaf node: %d entry - missing data descriptor.",
501
0
         function,
502
0
         leaf_node_index );
503
504
0
        goto on_error;
505
0
      }
506
0
      data_descriptor = leaf_resource_node_entry->data_descriptor;
507
508
0
      switch( internal_resource->resource_node_entry->type )
509
0
      {
510
0
        case LIBWRC_RESOURCE_TYPE_STRING_TABLE:
511
0
          result = libwrc_language_table_get_entry_by_identifier(
512
0
              (libwrc_language_table_t *) internal_resource->value,
513
0
              leaf_resource_node_entry->identifier,
514
0
              &existing_language_entry,
515
0
              error );
516
517
0
          if( result == -1 )
518
0
          {
519
0
            libcerror_error_set(
520
0
             error,
521
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
522
0
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
523
0
             "%s: unable to retrieve number of language entry: 0x%08" PRIx32 ".",
524
0
             function );
525
526
0
            goto on_error;
527
0
          }
528
0
          if( existing_language_entry != NULL )
529
0
          {
530
0
            language_entry = existing_language_entry;
531
0
          }
532
0
          else
533
0
          {
534
0
            if( libwrc_language_entry_initialize(
535
0
                 &language_entry,
536
0
                 leaf_resource_node_entry->identifier,
537
0
                 (int (*)(intptr_t **, libcerror_error_t **)) &libfvalue_value_free,
538
0
                 error ) != 1 )
539
0
            {
540
0
              libcerror_error_set(
541
0
               error,
542
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
543
0
               LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
544
0
               "%s: unable to create language entry.",
545
0
               function );
546
547
0
              goto on_error;
548
0
            }
549
0
          }
550
0
          break;
551
552
0
        case LIBWRC_RESOURCE_TYPE_MANIFEST:
553
0
        case LIBWRC_RESOURCE_TYPE_MESSAGE_TABLE:
554
0
          if( libwrc_language_entry_initialize(
555
0
               &language_entry,
556
0
               leaf_resource_node_entry->identifier,
557
0
               (int (*)(intptr_t **, libcerror_error_t **)) &libfvalue_value_free,
558
0
               error ) != 1 )
559
0
          {
560
0
            libcerror_error_set(
561
0
             error,
562
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
563
0
             LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
564
0
             "%s: unable to create language entry.",
565
0
             function );
566
567
0
            goto on_error;
568
0
          }
569
0
          break;
570
571
0
        case LIBWRC_RESOURCE_TYPE_MUI:
572
0
          if( libwrc_language_entry_initialize(
573
0
               &language_entry,
574
0
               leaf_resource_node_entry->identifier,
575
0
               (int (*)(intptr_t **, libcerror_error_t **)) &libwrc_mui_values_free,
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_INITIALIZE_FAILED,
582
0
             "%s: unable to create MUI values.",
583
0
             function );
584
585
0
            goto on_error;
586
0
          }
587
0
          break;
588
589
0
        case LIBWRC_RESOURCE_TYPE_VERSION_INFORMATION:
590
0
          if( libwrc_language_entry_initialize(
591
0
               &language_entry,
592
0
               leaf_resource_node_entry->identifier,
593
0
               (int (*)(intptr_t **, libcerror_error_t **)) &libwrc_version_values_free,
594
0
               error ) != 1 )
595
0
          {
596
0
            libcerror_error_set(
597
0
             error,
598
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
599
0
             LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
600
0
             "%s: unable to create version values.",
601
0
             function );
602
603
0
            goto on_error;
604
0
          }
605
0
          break;
606
0
      }
607
#if defined( HAVE_DEBUG_OUTPUT )
608
      switch( internal_resource->resource_node_entry->type )
609
      {
610
        case LIBWRC_RESOURCE_TYPE_STRING_TABLE:
611
          if( libcnotify_verbose != 0 )
612
          {
613
            libcnotify_printf(
614
             "%s: reading string: 0x%08" PRIx32 " for language identifier: 0x%08" PRIx32 " (%s)\n",
615
             function,
616
             sub_resource_node_entry->identifier - 1,
617
             leaf_resource_node_entry->identifier,
618
             libfwnt_locale_identifier_language_tag_get_identifier(
619
              leaf_resource_node_entry->identifier & 0x0000ffffUL ) );
620
          }
621
          break;
622
623
        case LIBWRC_RESOURCE_TYPE_MANIFEST:
624
        case LIBWRC_RESOURCE_TYPE_MESSAGE_TABLE:
625
        case LIBWRC_RESOURCE_TYPE_MUI:
626
        case LIBWRC_RESOURCE_TYPE_VERSION_INFORMATION:
627
          if( libcnotify_verbose != 0 )
628
          {
629
            libcnotify_printf(
630
             "%s: reading %s for language identifier: 0x%08" PRIx32 " (%s)\n",
631
             function,
632
             resource_type_string,
633
             leaf_resource_node_entry->identifier,
634
             libfwnt_locale_identifier_language_tag_get_identifier(
635
              leaf_resource_node_entry->identifier & 0x0000ffffUL ) );
636
          }
637
          break;
638
      }
639
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
640
641
0
      switch( internal_resource->resource_node_entry->type )
642
0
      {
643
0
        case LIBWRC_RESOURCE_TYPE_STRING_TABLE:
644
0
          result = libwrc_string_values_read(
645
0
                    language_entry,
646
0
                    internal_resource->io_handle,
647
0
                    internal_resource->file_io_handle,
648
0
                    sub_resource_node_entry->identifier - 1,
649
0
                    data_descriptor,
650
0
                    error );
651
0
          break;
652
653
0
        case LIBWRC_RESOURCE_TYPE_MESSAGE_TABLE:
654
0
          result = libwrc_message_table_values_read(
655
0
                    language_entry,
656
0
                    internal_resource->io_handle,
657
0
                    internal_resource->file_io_handle,
658
0
                    data_descriptor,
659
0
                    error );
660
0
          break;
661
662
0
        case LIBWRC_RESOURCE_TYPE_MANIFEST:
663
0
          result = libwrc_manifest_values_read(
664
0
                    language_entry,
665
0
                    internal_resource->io_handle,
666
0
                    internal_resource->file_io_handle,
667
0
                    data_descriptor,
668
0
                    error );
669
0
          break;
670
671
0
        case LIBWRC_RESOURCE_TYPE_MUI:
672
0
          result = libwrc_mui_values_read(
673
0
                    language_entry,
674
0
                    internal_resource->io_handle,
675
0
                    internal_resource->file_io_handle,
676
0
                    data_descriptor,
677
0
                    error );
678
0
          break;
679
680
0
        case LIBWRC_RESOURCE_TYPE_VERSION_INFORMATION:
681
0
          result = libwrc_version_values_read(
682
0
                    language_entry,
683
0
                    internal_resource->io_handle,
684
0
                    internal_resource->file_io_handle,
685
0
                    data_descriptor,
686
0
                    error );
687
0
          break;
688
689
#if defined( HAVE_DEBUG_OUTPUT )
690
        default:
691
          if( libwrc_resource_read_data_descriptor(
692
               internal_resource,
693
               internal_resource->io_handle,
694
               internal_resource->file_io_handle,
695
               data_descriptor,
696
               error ) != 1 )
697
          {
698
            libcerror_error_set(
699
             error,
700
             LIBCERROR_ERROR_DOMAIN_IO,
701
             LIBCERROR_IO_ERROR_READ_FAILED,
702
             "%s: unable to read unknown resource.",
703
             function );
704
705
            goto on_error;
706
          }
707
          break;
708
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
709
0
      }
710
0
      switch( internal_resource->resource_node_entry->type )
711
0
      {
712
0
        case LIBWRC_RESOURCE_TYPE_STRING_TABLE:
713
0
          if( result != 1 )
714
0
          {
715
0
            libcerror_error_set(
716
0
             error,
717
0
             LIBCERROR_ERROR_DOMAIN_IO,
718
0
             LIBCERROR_IO_ERROR_READ_FAILED,
719
0
             "%s: unable to read %s: 0x%08" PRIx32 " for language identifier: 0x%08" PRIx32 ".",
720
0
             function,
721
0
             resource_type_string,
722
0
             sub_resource_node_entry->identifier,
723
0
             leaf_resource_node_entry->identifier );
724
725
0
            goto on_error;
726
0
          }
727
0
          if( language_entry != existing_language_entry )
728
0
          {
729
0
            if( libwrc_language_table_append_entry(
730
0
                 (libwrc_language_table_t *) internal_resource->value,
731
0
                 &entry_index,
732
0
                 language_entry,
733
0
                 error ) != 1 )
734
0
            {
735
0
              libcerror_error_set(
736
0
               error,
737
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
738
0
               LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
739
0
               "%s: unable to append messages for language identifier: 0x%08" PRIx32 " to languages array.",
740
0
               function,
741
0
               leaf_resource_node_entry->identifier );
742
743
0
              goto on_error;
744
0
            }
745
0
          }
746
0
          language_entry = NULL;
747
748
0
          break;
749
750
0
        case LIBWRC_RESOURCE_TYPE_MANIFEST:
751
0
        case LIBWRC_RESOURCE_TYPE_MESSAGE_TABLE:
752
0
        case LIBWRC_RESOURCE_TYPE_MUI:
753
0
        case LIBWRC_RESOURCE_TYPE_VERSION_INFORMATION:
754
0
          if( result != 1 )
755
0
          {
756
0
            libcerror_error_set(
757
0
             error,
758
0
             LIBCERROR_ERROR_DOMAIN_IO,
759
0
             LIBCERROR_IO_ERROR_READ_FAILED,
760
0
             "%s: unable to read %s for language identifier: 0x%08" PRIx32 ".",
761
0
             function,
762
0
             resource_type_string,
763
0
             leaf_resource_node_entry->identifier );
764
765
0
            goto on_error;
766
0
          }
767
0
          if( libwrc_language_table_append_entry(
768
0
               (libwrc_language_table_t *) internal_resource->value,
769
0
               &entry_index,
770
0
               language_entry,
771
0
               error ) != 1 )
772
0
          {
773
0
            libcerror_error_set(
774
0
             error,
775
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
776
0
             LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
777
0
             "%s: unable to append %s for language identifier: 0x%08" PRIx32 " to languages array.",
778
0
             function,
779
0
             resource_type_string,
780
0
             leaf_resource_node_entry->identifier );
781
782
0
            goto on_error;
783
0
          }
784
0
          language_entry = NULL;
785
786
0
          break;
787
0
      }
788
0
    }
789
0
  }
790
0
  return( 1 );
791
792
0
on_error:
793
0
  if( ( language_entry != NULL )
794
0
   && ( language_entry != existing_language_entry ) )
795
0
  {
796
0
    libwrc_language_entry_free(
797
0
     &language_entry,
798
0
     NULL );
799
0
  }
800
0
  if( internal_resource->value != NULL )
801
0
  {
802
0
    if( internal_resource->free_value != NULL )
803
0
    {
804
0
      internal_resource->free_value(
805
0
       &( internal_resource->value ),
806
0
       NULL );
807
0
    }
808
0
    internal_resource->free_value = NULL;
809
0
  }
810
0
  return( -1 );
811
0
}
812
813
/* Reads a data descriptor
814
 * Returns 1 if successful or -1 on error
815
 */
816
int libwrc_resource_read_data_descriptor(
817
     libwrc_internal_resource_t *internal_resource,
818
     libwrc_io_handle_t *io_handle,
819
     libbfio_handle_t *file_io_handle,
820
     libwrc_data_descriptor_t *data_descriptor,
821
     libcerror_error_t **error )
822
0
{
823
0
  uint8_t *resource_data    = NULL;
824
0
  static char *function     = "libwrc_resource_read_data_descriptor";
825
0
  off64_t file_offset       = 0;
826
0
  size_t resource_data_size = 0;
827
0
  ssize_t read_count        = 0;
828
829
0
  if( internal_resource == NULL )
830
0
  {
831
0
    libcerror_error_set(
832
0
     error,
833
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
834
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
835
0
     "%s: invalid resource.",
836
0
     function );
837
838
0
    return( -1 );
839
0
  }
840
0
  if( io_handle == NULL )
841
0
  {
842
0
    libcerror_error_set(
843
0
     error,
844
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
845
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
846
0
     "%s: invalid IO handle.",
847
0
     function );
848
849
0
    return( -1 );
850
0
  }
851
0
  if( data_descriptor == NULL )
852
0
  {
853
0
    libcerror_error_set(
854
0
     error,
855
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
856
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
857
0
     "%s: invalid data descriptor.",
858
0
     function );
859
860
0
    return( -1 );
861
0
  }
862
0
  resource_data_size = (size_t) data_descriptor->size;
863
864
0
  if( ( resource_data_size == 0 )
865
0
   || ( resource_data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
866
0
  {
867
0
    libcerror_error_set(
868
0
     error,
869
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
870
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
871
0
     "%s: invalid resource data size value out of bounds.",
872
0
     function );
873
874
0
    goto on_error;
875
0
  }
876
0
  resource_data = (uint8_t *) memory_allocate(
877
0
                               sizeof( uint8_t ) * resource_data_size );
878
879
0
  if( resource_data == NULL )
880
0
  {
881
0
    libcerror_error_set(
882
0
     error,
883
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
884
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
885
0
     "%s: unable to create resource data.",
886
0
     function );
887
888
0
    goto on_error;
889
0
  }
890
0
  file_offset = data_descriptor->virtual_address - io_handle->virtual_address;
891
892
0
  read_count = libbfio_handle_read_buffer_at_offset(
893
0
                file_io_handle,
894
0
                resource_data,
895
0
                resource_data_size,
896
0
                file_offset,
897
0
                error );
898
899
0
  if( read_count != (ssize_t) resource_data_size )
900
0
  {
901
0
    libcerror_error_set(
902
0
     error,
903
0
     LIBCERROR_ERROR_DOMAIN_IO,
904
0
     LIBCERROR_IO_ERROR_READ_FAILED,
905
0
     "%s: unable to read resource data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
906
0
     function,
907
0
     file_offset,
908
0
     file_offset );
909
910
0
    goto on_error;
911
0
  }
912
#if defined( HAVE_DEBUG_OUTPUT )
913
  if( libcnotify_verbose != 0 )
914
  {
915
    libcnotify_printf(
916
     "%s: resource data:\n",
917
     function );
918
    libcnotify_print_data(
919
     resource_data,
920
     resource_data_size,
921
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
922
  }
923
#endif
924
0
  memory_free(
925
0
   resource_data );
926
927
0
  return( 1 );
928
929
0
on_error:
930
0
  if( resource_data != NULL )
931
0
  {
932
0
    memory_free(
933
0
     resource_data );
934
0
  }
935
0
  return( -1 );
936
0
}
937
938
/* Retrieves the resource identifier
939
 * Returns 1 if successful or -1 on error
940
 */
941
int libwrc_resource_get_identifier(
942
     libwrc_resource_t *resource,
943
     uint32_t *identifier,
944
     libcerror_error_t **error )
945
0
{
946
0
  libwrc_internal_resource_t *internal_resource = NULL;
947
0
  static char *function                         = "libwrc_resource_get_identifier";
948
949
0
  if( resource == NULL )
950
0
  {
951
0
    libcerror_error_set(
952
0
     error,
953
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
954
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
955
0
     "%s: invalid resource.",
956
0
     function );
957
958
0
    return( -1 );
959
0
  }
960
0
  internal_resource = (libwrc_internal_resource_t *) resource;
961
962
0
  if( libwrc_resource_node_entry_get_identifier(
963
0
       internal_resource->resource_node_entry,
964
0
       identifier,
965
0
       error ) != 1 )
966
0
  {
967
0
    libcerror_error_set(
968
0
     error,
969
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
970
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
971
0
     "%s: unable to retrieve identifier.",
972
0
     function );
973
974
0
    return( -1 );
975
0
  }
976
0
  return( 1 );
977
0
}
978
979
/* Retrieves the size of the UTF-8 encoded name
980
 * The returned size includes the end of string character
981
 * Returns 1 if successful, 0 if not available or -1 on error
982
 */
983
int libwrc_resource_get_utf8_name_size(
984
     libwrc_resource_t *resource,
985
     size_t *utf8_string_size,
986
     libcerror_error_t **error )
987
0
{
988
0
  libwrc_internal_resource_t *internal_resource = NULL;
989
0
  static char *function                         = "libwrc_resource_get_utf8_name_size";
990
0
  int result                                    = 0;
991
992
0
  if( resource == NULL )
993
0
  {
994
0
    libcerror_error_set(
995
0
     error,
996
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
997
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
998
0
     "%s: invalid resource.",
999
0
     function );
1000
1001
0
    return( -1 );
1002
0
  }
1003
0
  internal_resource = (libwrc_internal_resource_t *) resource;
1004
1005
0
  result = libwrc_resource_node_entry_get_utf8_name_size(
1006
0
            internal_resource->resource_node_entry,
1007
0
            utf8_string_size,
1008
0
            error );
1009
1010
0
  if( result == -1 )
1011
0
  {
1012
0
    libcerror_error_set(
1013
0
     error,
1014
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1015
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1016
0
     "%s: unable to retrieve size of UTF-8 name.",
1017
0
     function );
1018
1019
0
    return( -1 );
1020
0
  }
1021
0
  return( result );
1022
0
}
1023
1024
/* Retrieves the UTF-8 encoded name
1025
 * The size should include the end of string character
1026
 * Returns 1 if successful, 0 if not available or -1 on error
1027
 */
1028
int libwrc_resource_get_utf8_name(
1029
     libwrc_resource_t *resource,
1030
     uint8_t *utf8_string,
1031
     size_t utf8_string_size,
1032
     libcerror_error_t **error )
1033
0
{
1034
0
  libwrc_internal_resource_t *internal_resource = NULL;
1035
0
  static char *function                         = "libwrc_resource_get_utf8_name";
1036
0
  int result                                    = 0;
1037
1038
0
  if( resource == NULL )
1039
0
  {
1040
0
    libcerror_error_set(
1041
0
     error,
1042
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1043
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1044
0
     "%s: invalid resource.",
1045
0
     function );
1046
1047
0
    return( -1 );
1048
0
  }
1049
0
  internal_resource = (libwrc_internal_resource_t *) resource;
1050
1051
0
  result = libwrc_resource_node_entry_get_utf8_name(
1052
0
            internal_resource->resource_node_entry,
1053
0
            utf8_string,
1054
0
            utf8_string_size,
1055
0
            error );
1056
1057
0
  if( result == -1 )
1058
0
  {
1059
0
    libcerror_error_set(
1060
0
     error,
1061
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1062
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1063
0
     "%s: unable to retrieve size of UTF-8 name.",
1064
0
     function );
1065
1066
0
    return( -1 );
1067
0
  }
1068
0
  return( result );
1069
0
}
1070
1071
/* Retrieves the size of the UTF-16 encoded name
1072
 * The returned size includes the end of string character
1073
 * Returns 1 if successful, 0 if not available or -1 on error
1074
 */
1075
int libwrc_resource_get_utf16_name_size(
1076
     libwrc_resource_t *resource,
1077
     size_t *utf16_string_size,
1078
     libcerror_error_t **error )
1079
0
{
1080
0
  libwrc_internal_resource_t *internal_resource = NULL;
1081
0
  static char *function                         = "libwrc_resource_get_utf16_name_size";
1082
0
  int result                                    = 0;
1083
1084
0
  if( resource == NULL )
1085
0
  {
1086
0
    libcerror_error_set(
1087
0
     error,
1088
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1089
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1090
0
     "%s: invalid resource.",
1091
0
     function );
1092
1093
0
    return( -1 );
1094
0
  }
1095
0
  internal_resource = (libwrc_internal_resource_t *) resource;
1096
1097
0
  result = libwrc_resource_node_entry_get_utf16_name_size(
1098
0
            internal_resource->resource_node_entry,
1099
0
            utf16_string_size,
1100
0
            error );
1101
1102
0
  if( result == -1 )
1103
0
  {
1104
0
    libcerror_error_set(
1105
0
     error,
1106
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1107
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1108
0
     "%s: unable to retrieve size of UTF-16 name.",
1109
0
     function );
1110
1111
0
    return( -1 );
1112
0
  }
1113
0
  return( result );
1114
0
}
1115
1116
/* Retrieves the UTF-16 encoded name
1117
 * The size should include the end of string character
1118
 * Returns 1 if successful, 0 if not available or -1 on error
1119
 */
1120
int libwrc_resource_get_utf16_name(
1121
     libwrc_resource_t *resource,
1122
     uint16_t *utf16_string,
1123
     size_t utf16_string_size,
1124
     libcerror_error_t **error )
1125
0
{
1126
0
  libwrc_internal_resource_t *internal_resource = NULL;
1127
0
  static char *function                         = "libwrc_resource_get_utf16_name";
1128
0
  int result                                    = 0;
1129
1130
0
  if( resource == NULL )
1131
0
  {
1132
0
    libcerror_error_set(
1133
0
     error,
1134
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1135
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1136
0
     "%s: invalid resource.",
1137
0
     function );
1138
1139
0
    return( -1 );
1140
0
  }
1141
0
  internal_resource = (libwrc_internal_resource_t *) resource;
1142
1143
0
  result = libwrc_resource_node_entry_get_utf16_name(
1144
0
            internal_resource->resource_node_entry,
1145
0
            utf16_string,
1146
0
            utf16_string_size,
1147
0
            error );
1148
1149
0
  if( result == -1 )
1150
0
  {
1151
0
    libcerror_error_set(
1152
0
     error,
1153
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1154
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1155
0
     "%s: unable to retrieve size of UTF-16 name.",
1156
0
     function );
1157
1158
0
    return( -1 );
1159
0
  }
1160
0
  return( result );
1161
0
}
1162
1163
/* Retrieves the resource type
1164
 * Returns 1 if successful or -1 on error
1165
 */
1166
int libwrc_resource_get_type(
1167
     libwrc_resource_t *resource,
1168
     int *type,
1169
     libcerror_error_t **error )
1170
0
{
1171
0
  libwrc_internal_resource_t *internal_resource = NULL;
1172
0
  static char *function                         = "libwrc_resource_get_type";
1173
1174
0
  if( resource == NULL )
1175
0
  {
1176
0
    libcerror_error_set(
1177
0
     error,
1178
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1179
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1180
0
     "%s: invalid resource.",
1181
0
     function );
1182
1183
0
    return( -1 );
1184
0
  }
1185
0
  internal_resource = (libwrc_internal_resource_t *) resource;
1186
1187
0
  if( libwrc_resource_node_entry_get_type(
1188
0
       internal_resource->resource_node_entry,
1189
0
       type,
1190
0
       error ) != 1 )
1191
0
  {
1192
0
    libcerror_error_set(
1193
0
     error,
1194
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1195
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1196
0
     "%s: unable to retrieve type.",
1197
0
     function );
1198
1199
0
    return( -1 );
1200
0
  }
1201
0
  return( 1 );
1202
0
}
1203
1204
/* Retrieves the language specific value
1205
 * Returns 1 if successful or -1 on error
1206
 */
1207
int libwrc_resource_get_value_by_language_identifier(
1208
     libwrc_resource_t *resource,
1209
     int resource_type,
1210
     uint32_t language_identifier,
1211
     int value_index,
1212
     intptr_t **value,
1213
     libcerror_error_t **error )
1214
0
{
1215
0
  libwrc_internal_resource_t *internal_resource = NULL;
1216
0
  libwrc_language_entry_t *language_entry       = NULL;
1217
0
  static char *function                         = "libwrc_resource_get_value_by_language_identifier";
1218
1219
0
  if( resource == NULL )
1220
0
  {
1221
0
    libcerror_error_set(
1222
0
     error,
1223
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1224
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1225
0
     "%s: invalid resource.",
1226
0
     function );
1227
1228
0
    return( -1 );
1229
0
  }
1230
0
  internal_resource = (libwrc_internal_resource_t *) resource;
1231
1232
0
  if( internal_resource->resource_node_entry == NULL )
1233
0
  {
1234
0
    libcerror_error_set(
1235
0
     error,
1236
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1237
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1238
0
     "%s: invalid resource - missing resource node entry.",
1239
0
     function );
1240
1241
0
    return( -1 );
1242
0
  }
1243
0
  if( internal_resource->resource_node_entry->type != resource_type )
1244
0
  {
1245
0
    libcerror_error_set(
1246
0
     error,
1247
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1248
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1249
0
     "%s: invalid resource - invalid resource node entry - unsupported resource type: 0x%08" PRIx32 ".",
1250
0
     function,
1251
0
     internal_resource->resource_node_entry->type );
1252
1253
0
    return( -1 );
1254
0
  }
1255
0
  if( internal_resource->value == NULL )
1256
0
  {
1257
0
    if( libwrc_resource_read_value(
1258
0
         internal_resource,
1259
0
         error ) != 1 )
1260
0
    {
1261
0
      libcerror_error_set(
1262
0
       error,
1263
0
       LIBCERROR_ERROR_DOMAIN_IO,
1264
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1265
0
       "%s: unable to read resource value.",
1266
0
       function );
1267
1268
0
      return( -1 );
1269
0
    }
1270
0
  }
1271
0
  if( libwrc_language_table_get_entry_by_identifier(
1272
0
       (libwrc_language_table_t *) internal_resource->value,
1273
0
       language_identifier,
1274
0
       &language_entry,
1275
0
       error ) != 1 )
1276
0
  {
1277
0
    libcerror_error_set(
1278
0
     error,
1279
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1280
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1281
0
     "%s: unable to retrieve language entry for identifier: 0x%08" PRIx32 ".",
1282
0
     function,
1283
0
     language_identifier );
1284
1285
0
    return( -1 );
1286
0
  }
1287
0
  if( libwrc_language_entry_get_value_by_index(
1288
0
       language_entry,
1289
0
       value_index,
1290
0
       value,
1291
0
       error ) != 1 )
1292
0
  {
1293
0
    libcerror_error_set(
1294
0
     error,
1295
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1296
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1297
0
     "%s: unable to retrieve value: %d.",
1298
0
     function,
1299
0
     value_index );
1300
1301
0
    return( -1 );
1302
0
  }
1303
0
  return( 1 );
1304
0
}
1305
1306
/* Retrieves the number of items
1307
 * Returns 1 if successful or -1 on error
1308
 */
1309
int libwrc_resource_get_number_of_items(
1310
     libwrc_resource_t *resource,
1311
     int *number_of_items,
1312
     libcerror_error_t **error )
1313
0
{
1314
0
  libwrc_internal_resource_t *internal_resource = NULL;
1315
0
  static char *function                         = "libwrc_resource_get_number_of_items";
1316
1317
0
  if( resource == NULL )
1318
0
  {
1319
0
    libcerror_error_set(
1320
0
     error,
1321
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1322
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1323
0
     "%s: invalid resource.",
1324
0
     function );
1325
1326
0
    return( -1 );
1327
0
  }
1328
0
  internal_resource = (libwrc_internal_resource_t *) resource;
1329
1330
0
  if( libcdata_tree_node_get_number_of_sub_nodes(
1331
0
       internal_resource->resource_node,
1332
0
       number_of_items,
1333
0
       error ) != 1 )
1334
0
  {
1335
0
    libcerror_error_set(
1336
0
     error,
1337
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1338
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1339
0
     "%s: unable to retrieve number of resource sub nodes.",
1340
0
     function );
1341
1342
0
    return( -1 );
1343
0
  }
1344
0
  return( 1 );
1345
0
}
1346
1347
/* Retrieves a specific item
1348
 * Returns 1 if successful or -1 on error
1349
 */
1350
int libwrc_resource_get_item_by_index(
1351
     libwrc_resource_t *resource,
1352
     int item_index,
1353
     libwrc_resource_item_t **resource_item,
1354
     libcerror_error_t **error )
1355
0
{
1356
0
  libcdata_tree_node_t *resource_sub_node       = NULL;
1357
0
  libwrc_internal_resource_t *internal_resource = NULL;
1358
0
  static char *function                         = "libwrc_resource_get_item_by_index";
1359
1360
0
  if( resource == NULL )
1361
0
  {
1362
0
    libcerror_error_set(
1363
0
     error,
1364
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1365
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1366
0
     "%s: invalid resource.",
1367
0
     function );
1368
1369
0
    return( -1 );
1370
0
  }
1371
0
  internal_resource = (libwrc_internal_resource_t *) resource;
1372
1373
0
  if( libcdata_tree_node_get_sub_node_by_index(
1374
0
       internal_resource->resource_node,
1375
0
       item_index,
1376
0
       &resource_sub_node,
1377
0
       error ) != 1 )
1378
0
  {
1379
0
    libcerror_error_set(
1380
0
     error,
1381
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1382
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1383
0
     "%s: unable to retrieve resource sub node: %d.",
1384
0
     function,
1385
0
     item_index );
1386
1387
0
    return( -1 );
1388
0
  }
1389
0
  if( libwrc_resource_item_initialize(
1390
0
       resource_item,
1391
0
       internal_resource->io_handle,
1392
0
       internal_resource->file_io_handle,
1393
0
       resource_sub_node,
1394
0
       error ) != 1 )
1395
0
  {
1396
0
    libcerror_error_set(
1397
0
     error,
1398
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1399
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1400
0
     "%s: unable to create resource item.",
1401
0
     function );
1402
1403
0
    return( -1 );
1404
0
  }
1405
0
  return( 1 );
1406
0
}
1407