Coverage Report

Created: 2026-05-30 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwrc/libwrc/libwrc_resource_node_tree.c
Line
Count
Source
1
/*
2
 * Resource node tree functions
3
 *
4
 * Copyright (C) 2011-2026, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libwrc_definitions.h"
27
#include "libwrc_io_handle.h"
28
#include "libwrc_libbfio.h"
29
#include "libwrc_libcdata.h"
30
#include "libwrc_libcerror.h"
31
#include "libwrc_libcnotify.h"
32
#include "libwrc_resource_node_entry.h"
33
#include "libwrc_resource_node_header.h"
34
#include "libwrc_resource_node_tree.h"
35
36
#include "wrc_resource_node.h"
37
38
const uint8_t libwrc_resource_name_mui[ 6 ] = {
39
  'M', 0, 'U', 0, 'I', 0 };
40
41
const uint8_t libwrc_resource_name_wevt_template[ 26 ] = {
42
  'W', 0, 'E', 0, 'V', 0, 'T', 0, '_', 0, 'T', 0, 'E', 0, 'M', 0,
43
  'P', 0, 'L', 0, 'A', 0, 'T', 0, 'E', 0 };
44
45
/* Reads the node of a resource node tree
46
 * Returns 1 if successful or -1 on error
47
 */
48
int libwrc_resource_node_tree_read_node(
49
     libcdata_tree_node_t *node,
50
     libwrc_io_handle_t *io_handle,
51
     libbfio_handle_t *file_io_handle,
52
     off64_t file_offset,
53
     int node_level,
54
     libcerror_error_t **error )
55
5.33k
{
56
5.33k
  libcdata_tree_node_t *sub_node                        = NULL;
57
5.33k
  libwrc_resource_node_entry_t *resource_node_entry     = NULL;
58
5.33k
  libwrc_resource_node_entry_t *sub_resource_node_entry = NULL;
59
5.33k
  libwrc_resource_node_header_t *resource_node_header   = NULL;
60
5.33k
  static char *function                                 = "libwrc_resource_node_tree_read_node";
61
5.33k
  off64_t resource_node_entry_data_offset               = 0;
62
5.33k
  uint32_t entry_index                                  = 0;
63
5.33k
  uint32_t number_of_entries                            = 0;
64
5.33k
  uint32_t resource_node_entry_offset                   = 0;
65
5.33k
  int number_of_sub_nodes                               = 0;
66
5.33k
  int resource_node_entry_index                         = 0;
67
5.33k
  int result                                            = 0;
68
5.33k
  int sub_node_index                                    = 0;
69
70
5.33k
  if( io_handle == NULL )
71
0
  {
72
0
    libcerror_error_set(
73
0
     error,
74
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
75
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
76
0
     "%s: invalid IO handle.",
77
0
     function );
78
79
0
    return( -1 );
80
0
  }
81
5.33k
  if( ( node_level < 1 )
82
5.33k
   || ( node_level > LIBWRC_MAXIMUM_RESOURCE_NODE_RECURSION_DEPTH ) )
83
28
  {
84
28
    libcerror_error_set(
85
28
     error,
86
28
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
87
28
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
88
28
     "%s: invalid node level value out of bounds.",
89
28
     function );
90
91
28
    return( -1 );
92
28
  }
93
5.31k
  if( node == NULL )
94
0
  {
95
0
    libcerror_error_set(
96
0
     error,
97
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
98
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
99
0
     "%s: invalid node.",
100
0
     function );
101
102
0
    return( -1 );
103
0
  }
104
5.31k
  if( libwrc_resource_node_header_initialize(
105
5.31k
       &resource_node_header,
106
5.31k
       error ) == -1 )
107
0
  {
108
0
    libcerror_error_set(
109
0
     error,
110
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
111
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
112
0
     "%s: unable to create resource node header.",
113
0
     function );
114
115
0
    goto on_error;
116
0
  }
117
5.31k
  if( libwrc_resource_node_header_read_file_io_handle(
118
5.31k
       resource_node_header,
119
5.31k
       file_io_handle,
120
5.31k
       file_offset,
121
5.31k
       error ) != 1 )
122
130
  {
123
130
    libcerror_error_set(
124
130
     error,
125
130
     LIBCERROR_ERROR_DOMAIN_IO,
126
130
     LIBCERROR_IO_ERROR_READ_FAILED,
127
130
     "%s: unable to read resource node header at offset: %" PRIi64 " (0x%08" PRIx64 ").",
128
130
     function,
129
130
     file_offset,
130
130
     file_offset );
131
132
130
    goto on_error;
133
130
  }
134
5.18k
  file_offset += sizeof( wrc_resource_node_header_t );
135
136
5.18k
  number_of_entries = (uint32_t) resource_node_header->number_of_named_entries + (uint32_t) resource_node_header->number_of_unnamed_entries;
137
138
5.18k
  if( libwrc_resource_node_header_free(
139
5.18k
       &resource_node_header,
140
5.18k
       error ) == -1 )
141
0
  {
142
0
    libcerror_error_set(
143
0
     error,
144
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
145
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
146
0
     "%s: unable to free resource node header.",
147
0
     function );
148
149
0
    goto on_error;
150
0
  }
151
5.18k
  resource_node_entry_data_offset = sizeof( wrc_resource_node_header_t ) + ( number_of_entries * sizeof( wrc_resource_node_entry_t ) );
152
153
5.18k
  if( (size64_t) resource_node_entry_data_offset > io_handle->stream_size )
154
27
  {
155
27
    libcerror_error_set(
156
27
     error,
157
27
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
158
27
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
159
27
     "%s: invalid number of entries value out of bounds.",
160
27
     function );
161
162
27
    goto on_error;
163
27
  }
164
5.15k
  for( entry_index = 0;
165
15.3k
       entry_index < number_of_entries;
166
10.2k
       entry_index++ )
167
10.4k
  {
168
10.4k
    if( libwrc_resource_node_entry_initialize(
169
10.4k
         &resource_node_entry,
170
10.4k
         error ) == -1 )
171
0
    {
172
0
      libcerror_error_set(
173
0
       error,
174
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
175
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
176
0
       "%s: unable to create resource node entry: %d.",
177
0
       function,
178
0
       entry_index );
179
180
0
      goto on_error;
181
0
    }
182
10.4k
    if( libwrc_resource_node_entry_read_file_io_handle(
183
10.4k
         resource_node_entry,
184
10.4k
         file_io_handle,
185
10.4k
         file_offset,
186
10.4k
         node_level,
187
10.4k
         error ) != 1 )
188
6
    {
189
6
      libcerror_error_set(
190
6
       error,
191
6
       LIBCERROR_ERROR_DOMAIN_IO,
192
6
       LIBCERROR_IO_ERROR_READ_FAILED,
193
6
       "%s: unable to read resource node entry: %d at offset: %" PRIi64 " (0x%08" PRIx64 ").",
194
6
       function,
195
6
       entry_index,
196
6
       file_offset,
197
6
       file_offset );
198
199
6
      goto on_error;
200
6
    }
201
10.4k
    file_offset += sizeof( wrc_resource_node_entry_t );
202
203
10.4k
    result = libwrc_resource_node_entry_read_name_file_io_handle(
204
10.4k
              resource_node_entry,
205
10.4k
              file_io_handle,
206
10.4k
              error );
207
208
10.4k
    if( result == -1 )
209
147
    {
210
147
      libcerror_error_set(
211
147
       error,
212
147
       LIBCERROR_ERROR_DOMAIN_IO,
213
147
       LIBCERROR_IO_ERROR_READ_FAILED,
214
147
       "%s: unable to read resource node entry: %d name.",
215
147
       function,
216
147
       entry_index );
217
218
147
      goto on_error;
219
147
    }
220
10.3k
    resource_node_entry_offset = resource_node_entry->offset & 0x7fffffffUL;
221
222
    /* Check the bounds here to fail fast on corrupt data
223
     */
224
10.3k
    if( ( resource_node_entry_offset < resource_node_entry_data_offset )
225
10.3k
     || ( resource_node_entry_offset >= io_handle->stream_size ) )
226
95
    {
227
95
      libcerror_error_set(
228
95
       error,
229
95
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
230
95
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
231
95
       "%s: invalid resource node entry: %d - offset value out of bounds.",
232
95
       function,
233
95
       entry_index );
234
235
95
      goto on_error;
236
95
    }
237
10.2k
    if( node_level == 1 )
238
1.79k
    {
239
1.79k
      if( ( resource_node_entry->identifier & LIBWRC_RESOURCE_IDENTIFIER_FLAG_HAS_NAME ) == 0 )
240
1.14k
      {
241
1.14k
        switch( resource_node_entry->identifier )
242
1.14k
        {
243
12
          case LIBWRC_RESOURCE_IDENTIFIER_CURSOR:
244
12
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_CURSOR;
245
12
            break;
246
247
32
          case LIBWRC_RESOURCE_IDENTIFIER_BITMAP:
248
32
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_BITMAP;
249
32
            break;
250
251
4
          case LIBWRC_RESOURCE_IDENTIFIER_ICON:
252
4
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_ICON;
253
4
            break;
254
255
6
          case LIBWRC_RESOURCE_IDENTIFIER_MENU:
256
6
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_MENU;
257
6
            break;
258
259
9
          case LIBWRC_RESOURCE_IDENTIFIER_DIALOG:
260
9
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_DIALOG;
261
9
            break;
262
263
1
          case LIBWRC_RESOURCE_IDENTIFIER_STRING:
264
1
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_STRING;
265
1
            break;
266
267
0
          case LIBWRC_RESOURCE_IDENTIFIER_FONT_DIRECTORY:
268
0
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_FONT_DIRECTORY;
269
0
            break;
270
271
2
          case LIBWRC_RESOURCE_IDENTIFIER_FONT:
272
2
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_FONT;
273
2
            break;
274
275
13
          case LIBWRC_RESOURCE_IDENTIFIER_ACCELERATOR:
276
13
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_ACCELERATOR;
277
13
            break;
278
279
1
          case LIBWRC_RESOURCE_IDENTIFIER_RAW_DATA:
280
1
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_RAW_DATA;
281
1
            break;
282
283
3
          case LIBWRC_RESOURCE_IDENTIFIER_MESSAGE_TABLE:
284
3
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_MESSAGE_TABLE;
285
3
            break;
286
287
37
          case LIBWRC_RESOURCE_IDENTIFIER_GROUP_CURSOR:
288
37
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_GROUP_CURSOR;
289
37
            break;
290
291
1
          case LIBWRC_RESOURCE_IDENTIFIER_GROUP_ICON:
292
1
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_GROUP_ICON;
293
1
            break;
294
295
8
          case LIBWRC_RESOURCE_IDENTIFIER_VERSION:
296
8
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_VERSION;
297
8
            break;
298
299
9
          case LIBWRC_RESOURCE_IDENTIFIER_DIALOG_INCLUDE:
300
9
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_DIALOG_INCLUDE;
301
9
            break;
302
303
7
          case LIBWRC_RESOURCE_IDENTIFIER_PLUG_AND_PLAY:
304
7
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_PLUG_AND_PLAY;
305
7
            break;
306
307
5
          case LIBWRC_RESOURCE_IDENTIFIER_VXD:
308
5
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_VXD;
309
5
            break;
310
311
15
          case LIBWRC_RESOURCE_IDENTIFIER_ANIMATED_CURSOR:
312
15
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_ANIMATED_CURSOR;
313
15
            break;
314
315
9
          case LIBWRC_RESOURCE_IDENTIFIER_ANIMATED_ICON:
316
9
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_ANIMATED_ICON;
317
9
            break;
318
319
8
          case LIBWRC_RESOURCE_IDENTIFIER_HTML:
320
8
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_HTML;
321
8
            break;
322
323
26
          case LIBWRC_RESOURCE_IDENTIFIER_MANIFEST:
324
26
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_MANIFEST;
325
26
            break;
326
1.14k
        }
327
1.14k
      }
328
655
      else
329
655
      {
330
655
        if( resource_node_entry->name_string_size == 6 )
331
233
        {
332
233
          if( memory_compare(
333
233
               resource_node_entry->name_string,
334
233
               libwrc_resource_name_mui,
335
233
               6 ) == 0 )
336
71
          {
337
71
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_MUI;
338
71
          }
339
233
        }
340
422
        else if( resource_node_entry->name_string_size == 26 )
341
248
        {
342
248
          if( memory_compare(
343
248
               resource_node_entry->name_string,
344
248
               libwrc_resource_name_wevt_template,
345
248
               26 ) == 0 )
346
67
          {
347
67
            resource_node_entry->type = LIBWRC_RESOURCE_TYPE_WEVT_TEMPLATE;
348
67
          }
349
248
        }
350
655
      }
351
1.79k
    }
352
10.2k
    if( libcdata_tree_node_insert_value(
353
10.2k
         node,
354
10.2k
         (intptr_t *) resource_node_entry,
355
10.2k
         (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libwrc_resource_node_entry_compare,
356
10.2k
         LIBCDATA_INSERT_FLAG_NON_UNIQUE_ENTRIES,
357
10.2k
         error ) == -1 )
358
0
    {
359
0
      libcerror_error_set(
360
0
       error,
361
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
362
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
363
0
       "%s: unable to insert resource node: %d.",
364
0
       function,
365
0
       resource_node_entry_index );
366
367
0
      goto on_error;
368
0
    }
369
10.2k
    resource_node_entry = NULL;
370
371
10.2k
    resource_node_entry_index++;
372
373
#if defined( HAVE_DEBUG_OUTPUT )
374
    if( libcnotify_verbose != 0 )
375
    {
376
      libcnotify_printf(
377
       "\n" );
378
    }
379
#endif
380
10.2k
  }
381
4.90k
  if( libcdata_tree_node_get_number_of_sub_nodes(
382
4.90k
       node,
383
4.90k
       &number_of_sub_nodes,
384
4.90k
       error ) != 1 )
385
0
  {
386
0
    libcerror_error_set(
387
0
     error,
388
0
     LIBCERROR_ERROR_DOMAIN_IO,
389
0
     LIBCERROR_IO_ERROR_READ_FAILED,
390
0
     "%s: unable to retrieve number of sub nodes.",
391
0
     function );
392
393
0
    goto on_error;
394
0
  }
395
4.90k
  if( libcdata_tree_node_get_sub_node_by_index(
396
4.90k
       node,
397
4.90k
       0,
398
4.90k
       &sub_node,
399
4.90k
       error ) != 1 )
400
32
  {
401
32
    libcerror_error_set(
402
32
     error,
403
32
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
404
32
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
405
32
     "%s: unable to retrieve first sub node.",
406
32
     function );
407
408
32
    goto on_error;
409
32
  }
410
4.87k
  for( sub_node_index = 0;
411
7.88k
       sub_node_index < number_of_sub_nodes;
412
4.87k
       sub_node_index++ )
413
7.13k
  {
414
7.13k
    if( libcdata_tree_node_get_value(
415
7.13k
         sub_node,
416
7.13k
         (intptr_t **) &sub_resource_node_entry,
417
7.13k
         error ) != 1 )
418
0
    {
419
0
      libcerror_error_set(
420
0
       error,
421
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
422
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
423
0
       "%s: unable to retrieve resource sub node: %d entry.",
424
0
       function,
425
0
       sub_node_index );
426
427
0
      goto on_error;
428
0
    }
429
7.13k
    if( sub_resource_node_entry == NULL )
430
0
    {
431
0
      libcerror_error_set(
432
0
       error,
433
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
434
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
435
0
       "%s: invalid resource sub node: %d entry.",
436
0
       function,
437
0
       sub_node_index );
438
439
0
      goto on_error;
440
0
    }
441
7.13k
    if( ( sub_resource_node_entry->offset & 0x80000000UL ) != 0 )
442
4.45k
    {
443
4.45k
      resource_node_entry_offset = sub_resource_node_entry->offset & 0x7fffffffUL;
444
445
4.45k
      if( libwrc_resource_node_tree_read_node(
446
4.45k
           sub_node,
447
4.45k
           io_handle,
448
4.45k
           file_io_handle,
449
4.45k
           (off64_t) resource_node_entry_offset,
450
4.45k
           node_level + 1,
451
4.45k
           error ) != 1 )
452
3.76k
      {
453
3.76k
        libcerror_error_set(
454
3.76k
         error,
455
3.76k
         LIBCERROR_ERROR_DOMAIN_IO,
456
3.76k
         LIBCERROR_IO_ERROR_READ_FAILED,
457
3.76k
         "%s: unable to read sub resource node: %d at offset: %" PRIu32 " (0x%08" PRIx32 ").",
458
3.76k
         function,
459
3.76k
         sub_node_index,
460
3.76k
         resource_node_entry_offset,
461
3.76k
         resource_node_entry_offset );
462
463
3.76k
        goto on_error;
464
3.76k
      }
465
4.45k
    }
466
2.68k
    else
467
2.68k
    {
468
2.68k
      if( libwrc_data_descriptor_initialize(
469
2.68k
           &( sub_resource_node_entry->data_descriptor ),
470
2.68k
           error ) == -1 )
471
0
      {
472
0
        libcerror_error_set(
473
0
         error,
474
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
475
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
476
0
         "%s: unable to create data descriptor: %d.",
477
0
         function,
478
0
         sub_node_index );
479
480
0
        goto on_error;
481
0
      }
482
2.68k
      if( libwrc_data_descriptor_read_file_io_handle(
483
2.68k
           sub_resource_node_entry->data_descriptor,
484
2.68k
           file_io_handle,
485
2.68k
           (off64_t) sub_resource_node_entry->offset,
486
2.68k
           error ) != 1 )
487
173
      {
488
173
        libcerror_error_set(
489
173
         error,
490
173
         LIBCERROR_ERROR_DOMAIN_IO,
491
173
         LIBCERROR_IO_ERROR_READ_FAILED,
492
173
         "%s: unable to read data descriptor: %d at offset: %" PRIu32 " (0x%08" PRIx32 ").",
493
173
         function,
494
173
         sub_node_index,
495
173
         sub_resource_node_entry->offset,
496
173
         sub_resource_node_entry->offset );
497
498
173
        goto on_error;
499
173
      }
500
2.51k
      if( ( sub_resource_node_entry->data_descriptor->virtual_address < io_handle->virtual_address )
501
2.51k
       || ( (size64_t) sub_resource_node_entry->data_descriptor->virtual_address >= ( io_handle->virtual_address + io_handle->stream_size ) ) )
502
144
      {
503
144
        libcerror_error_set(
504
144
         error,
505
144
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
506
144
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
507
144
         "%s: invalid data descriptor: %d - virtual address value out of bounds.",
508
144
         function,
509
144
         sub_node_index );
510
511
144
        goto on_error;
512
144
      }
513
2.36k
      if( (size64_t) ( sub_resource_node_entry->data_descriptor->virtual_address + sub_resource_node_entry->data_descriptor->size ) > ( io_handle->virtual_address + io_handle->stream_size ) )
514
46
      {
515
46
        libcerror_error_set(
516
46
         error,
517
46
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
518
46
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
519
46
         "%s: invalid data descriptor: %d - size value out of bounds.",
520
46
         function,
521
46
         sub_node_index );
522
523
46
        goto on_error;
524
46
      }
525
2.36k
    }
526
3.01k
    if( libcdata_tree_node_get_next_node(
527
3.01k
         sub_node,
528
3.01k
         &sub_node,
529
3.01k
         error ) != 1 )
530
0
    {
531
0
      libcerror_error_set(
532
0
       error,
533
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
534
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
535
0
       "%s: unable to retrieve next node of sub node: %d.",
536
0
       function,
537
0
       sub_node_index );
538
539
0
      goto on_error;
540
0
    }
541
3.01k
  }
542
749
  return( 1 );
543
544
4.56k
on_error:
545
4.56k
  if( resource_node_entry != NULL )
546
248
  {
547
248
    libwrc_resource_node_entry_free(
548
248
     &resource_node_entry,
549
248
     NULL );
550
248
  }
551
4.56k
  if( resource_node_header != NULL )
552
130
  {
553
130
    libwrc_resource_node_header_free(
554
130
     &resource_node_header,
555
     NULL );
556
130
  }
557
4.56k
  return( -1 );
558
4.87k
}
559