Coverage Report

Created: 2026-08-31 07:43

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