GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_binres_language_table_load.c Lines: 144 144 100.0 %
Date: 2024-12-05 08:52:37 Branches: 52 52 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** GUIX Component                                                        */
16
/**                                                                       */
17
/**   Binres Loader Management (Binres Loader)                            */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define GX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_binres_loader.h"
28
#include "gx_system.h"
29
#include "gx_utility.h"
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _gx_binres_resource_header_load                     PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    This function reads resource header from a binary data buffer.      */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    info                                  Binary read control block     */
48
/*    header                                Returned resource header      */
49
/*                                                                        */
50
/*  OUTPUT                                                                */
51
/*                                                                        */
52
/*    Status                                Completion status             */
53
/*                                                                        */
54
/*  CALLS                                                                 */
55
/*                                                                        */
56
/*    None                                                                */
57
/*                                                                        */
58
/*  CALLED BY                                                             */
59
/*                                                                        */
60
/*    GUIX Internal Code                                                  */
61
/*                                                                        */
62
/*  RELEASE HISTORY                                                       */
63
/*                                                                        */
64
/*    DATE              NAME                      DESCRIPTION             */
65
/*                                                                        */
66
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
67
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
68
/*                                            removed use of memcpy,      */
69
/*                                            resulting in version 6.1    */
70
/*                                                                        */
71
/**************************************************************************/
72
#ifdef GX_BINARY_RESOURCE_SUPPORT
73
189
UINT _gx_binres_resource_header_load(GX_BINRES_DATA_INFO *info, GX_RESOURCE_HEADER *header)
74
{
75
189
    GX_BINRES_READ_USHORT(header -> gx_resource_header_magic_number, info -> gx_binres_root_address + info -> gx_binres_read_offset);
76
189
    info -> gx_binres_read_offset += sizeof(USHORT);
77
78
189
    GX_BINRES_READ_USHORT(header -> gx_resource_header_version, info -> gx_binres_root_address + info -> gx_binres_read_offset);
79
189
    info -> gx_binres_read_offset += sizeof(USHORT);
80
81
189
    GX_BINRES_READ_USHORT(header -> gx_resource_header_theme_count, info -> gx_binres_root_address + info -> gx_binres_read_offset);
82
189
    info -> gx_binres_read_offset += sizeof(USHORT);
83
84
189
    GX_BINRES_READ_USHORT(header -> gx_resource_header_language_count, info -> gx_binres_root_address + info -> gx_binres_read_offset);
85
189
    info -> gx_binres_read_offset += sizeof(USHORT);
86
87
189
    GX_BINRES_READ_ULONG(header -> gx_resource_header_theme_data_size, info -> gx_binres_root_address + info -> gx_binres_read_offset);
88
189
    info -> gx_binres_read_offset += sizeof(ULONG);
89
90
189
    GX_BINRES_READ_ULONG(header -> gx_resource_header_string_data_size, info -> gx_binres_root_address + info -> gx_binres_read_offset);
91
189
    info -> gx_binres_read_offset += sizeof(ULONG);
92
93
189
    GX_BINRES_READ_ULONG(header -> gx_resource_header_data_size, info -> gx_binres_root_address + info -> gx_binres_read_offset);
94
189
    info -> gx_binres_read_offset += sizeof(ULONG);
95
96
189
    return GX_SUCCESS;
97
}
98
#endif
99
100
/**************************************************************************/
101
/*                                                                        */
102
/*  FUNCTION                                               RELEASE        */
103
/*                                                                        */
104
/*    _gx_binres_string_header_load                       PORTABLE C      */
105
/*                                                           6.1          */
106
/*  AUTHOR                                                                */
107
/*                                                                        */
108
/*    Kenneth Maxwell, Microsoft Corporation                              */
109
/*                                                                        */
110
/*  DESCRIPTION                                                           */
111
/*                                                                        */
112
/*    This function reads string header from a binary data buffer.        */
113
/*                                                                        */
114
/*  INPUT                                                                 */
115
/*                                                                        */
116
/*    info                                  Binary read control block     */
117
/*    header                                Returned string header        */
118
/*                                                                        */
119
/*  OUTPUT                                                                */
120
/*                                                                        */
121
/*    Status                                Completion status             */
122
/*                                                                        */
123
/*  CALLS                                                                 */
124
/*                                                                        */
125
/*    None                                                                */
126
/*                                                                        */
127
/*  CALLED BY                                                             */
128
/*                                                                        */
129
/*    GUIX Internal Code                                                  */
130
/*                                                                        */
131
/*  RELEASE HISTORY                                                       */
132
/*                                                                        */
133
/*    DATE              NAME                      DESCRIPTION             */
134
/*                                                                        */
135
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
136
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
137
/*                                            removed use of memcpy,      */
138
/*                                            resulting in version 6.1    */
139
/*                                                                        */
140
/**************************************************************************/
141
#ifdef GX_BINARY_RESOURCE_SUPPORT
142
83
UINT _gx_binres_string_header_load(GX_BINRES_DATA_INFO *info, GX_STRING_HEADER *header)
143
{
144
83
    GX_BINRES_READ_USHORT(header -> gx_string_header_magic_number, info -> gx_binres_root_address + info -> gx_binres_read_offset);
145
83
    info -> gx_binres_read_offset += sizeof(USHORT);
146
147
83
    GX_BINRES_READ_USHORT(header -> gx_string_header_language_count, info -> gx_binres_root_address + info -> gx_binres_read_offset);
148
83
    info -> gx_binres_read_offset += sizeof(USHORT);
149
150
83
    GX_BINRES_READ_USHORT(header -> gx_string_header_string_count, info -> gx_binres_root_address + info -> gx_binres_read_offset);
151
83
    info -> gx_binres_read_offset += sizeof(USHORT);
152
153
83
    GX_BINRES_READ_ULONG(header -> gx_string_header_data_size, info -> gx_binres_root_address + info -> gx_binres_read_offset);
154
83
    info -> gx_binres_read_offset += sizeof(ULONG);
155
156
83
    return GX_SUCCESS;
157
}
158
#endif
159
160
/**************************************************************************/
161
/*                                                                        */
162
/*  FUNCTION                                               RELEASE        */
163
/*                                                                        */
164
/*    _gx_binres_language_header_load                     PORTABLE C      */
165
/*                                                           6.1          */
166
/*  AUTHOR                                                                */
167
/*                                                                        */
168
/*    Kenneth Maxwell, Microsoft Corporation                              */
169
/*                                                                        */
170
/*  DESCRIPTION                                                           */
171
/*                                                                        */
172
/*    This function reads language header from a binary data buffer.      */
173
/*                                                                        */
174
/*  INPUT                                                                 */
175
/*                                                                        */
176
/*    info                                  Binary read control block     */
177
/*    header                                Returned language header      */
178
/*                                                                        */
179
/*  OUTPUT                                                                */
180
/*                                                                        */
181
/*    Status                                Completion status             */
182
/*                                                                        */
183
/*  CALLS                                                                 */
184
/*                                                                        */
185
/*    None                                                                */
186
/*                                                                        */
187
/*  CALLED BY                                                             */
188
/*                                                                        */
189
/*    GUIX Internal Code                                                  */
190
/*                                                                        */
191
/*  RELEASE HISTORY                                                       */
192
/*                                                                        */
193
/*    DATE              NAME                      DESCRIPTION             */
194
/*                                                                        */
195
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
196
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
197
/*                                            removed use of memcpy,      */
198
/*                                            resulting in version 6.1    */
199
/*                                                                        */
200
/**************************************************************************/
201
#ifdef GX_BINARY_RESOURCE_SUPPORT
202
36
UINT _gx_binres_language_header_load(GX_BINRES_DATA_INFO *info, GX_LANGUAGE_HEADER *header)
203
{
204
36
    GX_BINRES_READ_USHORT(header -> gx_language_header_magic_number, info -> gx_binres_root_address + info -> gx_binres_read_offset);
205
36
    info -> gx_binres_read_offset += sizeof(USHORT);
206
207
36
    GX_BINRES_READ_USHORT(header -> gx_language_header_index, info -> gx_binres_root_address + info -> gx_binres_read_offset);
208
36
    info -> gx_binres_read_offset += sizeof(USHORT);
209
210
36
    memcpy(&header->gx_language_header_name, info->gx_binres_root_address + info->gx_binres_read_offset, sizeof(header->gx_language_header_name)); /* Use case of memcpy is verified. */
211
36
    info -> gx_binres_read_offset += sizeof(header -> gx_language_header_name);
212
213
36
    GX_BINRES_READ_ULONG(header -> gx_language_header_data_size, info -> gx_binres_root_address + info -> gx_binres_read_offset);
214
36
    info -> gx_binres_read_offset += sizeof(ULONG);
215
216
36
    return GX_SUCCESS;
217
}
218
#endif
219
220
/**************************************************************************/
221
/*                                                                        */
222
/*  FUNCTION                                               RELEASE        */
223
/*                                                                        */
224
/*    _gx_binres_language_table_buffer_allocate           PORTABLE C      */
225
/*                                                           6.1.7        */
226
/*  AUTHOR                                                                */
227
/*                                                                        */
228
/*    Kenneth Maxwell, Microsoft Corporation                              */
229
/*                                                                        */
230
/*  DESCRIPTION                                                           */
231
/*                                                                        */
232
/*    This function allocates needed memory buffer for loading language   */
233
/*    table.                                                              */
234
/*                                                                        */
235
/*  INPUT                                                                 */
236
/*                                                                        */
237
/*    info                                  Binary resource control block */
238
/*    language_table_type_size              Size of language table type   */
239
/*    string_table_type_size                Size of string table type     */
240
/*                                                                        */
241
/*  OUTPUT                                                                */
242
/*                                                                        */
243
/*    Status                                Completion status             */
244
/*                                                                        */
245
/*  CALLS                                                                 */
246
/*                                                                        */
247
/*    _gx_system_memory_allocator           Application defined memory    */
248
/*                                            allocation function         */
249
/*    _gx_binres_resource_header_load       Read binary resource header   */
250
/*    _gx_binres_string_header_load         Read string data header       */
251
/*                                                                        */
252
/*  CALLED BY                                                             */
253
/*                                                                        */
254
/*    GUIX Internal Code                                                  */
255
/*                                                                        */
256
/*  RELEASE HISTORY                                                       */
257
/*                                                                        */
258
/*    DATE              NAME                      DESCRIPTION             */
259
/*                                                                        */
260
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
261
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
262
/*                                            resulting in version 6.1    */
263
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
264
/*                                            test for langauge_count == 0*/
265
/*                                            resulting in version 6.1.7  */
266
/*                                                                        */
267
/**************************************************************************/
268
#ifdef GX_BINARY_RESOURCE_SUPPORT
269
46
static UINT _gx_binres_language_table_buffer_allocate(GX_BINRES_DATA_INFO *info, GX_UBYTE language_table_type_size, GX_UBYTE string_table_type_size)
270
{
271
GX_RESOURCE_HEADER res_header;
272
GX_STRING_HEADER   string_header;
273
USHORT             language_count;
274
USHORT             string_count;
275
UINT               language_table_size;
276
UINT               string_table_size;
277
278
46
    info -> gx_binres_read_offset = 0;
279
280
    /* Read resource header.  */
281
46
    _gx_binres_resource_header_load(info, &res_header);
282
46
    info -> gx_binres_read_offset += res_header.gx_resource_header_theme_data_size;
283
284
46
    if (res_header.gx_resource_header_magic_number != GX_MAGIC_NUMBER)
285
    {
286
2
        return GX_INVALID_FORMAT;
287
    }
288
289
44
    _gx_binres_string_header_load(info, &string_header);
290
291
44
    if (string_header.gx_string_header_magic_number != GX_MAGIC_NUMBER)
292
    {
293
2
        return GX_INVALID_FORMAT;
294
    }
295
296
42
    language_count = string_header.gx_string_header_language_count;
297
298
42
    if (language_count == 0)
299
    {
300
2
        return GX_INVALID_FORMAT;
301
    }
302
40
    string_count = string_header.gx_string_header_string_count;
303
304
    /* Calcualte memory size needed for string tables. */
305
40
    string_table_size = (UINT)(string_count * string_table_type_size);
306
40
    GX_UTILITY_MATH_UINT_MULT(string_table_size, language_count, string_table_size)
307
308
    /* Calculate memory size needed for language table. */
309
38
    language_table_size = (UINT)(language_table_type_size * language_count);
310
311
    /* Calculate memory size needed.  */
312
38
    GX_UTILITY_MATH_UINT_ADD(string_table_size, language_table_size, info -> gx_binres_buffer_size)
313
314
37
    info -> gx_binres_buffer = (GX_UBYTE *)_gx_system_memory_allocator(info -> gx_binres_buffer_size);
315
316
37
    if (!info -> gx_binres_buffer)
317
    {
318
3
        return GX_SYSTEM_MEMORY_ERROR;
319
    }
320
321
34
    memset(info -> gx_binres_buffer, 0, info -> gx_binres_buffer_size);
322
34
    info -> gx_binres_buffer_index = 0;
323
324
34
    return GX_SUCCESS;
325
}
326
#endif
327
328
/**************************************************************************/
329
/*                                                                        */
330
/*  FUNCTION                                               RELEASE        */
331
/*                                                                        */
332
/*    _gx_binres_language_table_load                      PORTABLE C      */
333
/*                                                           6.1          */
334
/*  AUTHOR                                                                */
335
/*                                                                        */
336
/*    Kenneth Maxwell, Microsoft Corporation                              */
337
/*                                                                        */
338
/*  DESCRIPTION (deprecated)                                              */
339
/*                                                                        */
340
/*    This service loads a language table from a binary data buffer.      */
341
/*                                                                        */
342
/*  INPUT                                                                 */
343
/*                                                                        */
344
/*    root_address                          Root address of binary        */
345
/*                                            resource data               */
346
/*    returned_language_table               Pointer to loaded language    */
347
/*                                           table                        */
348
/*                                                                        */
349
/*  OUTPUT                                                                */
350
/*                                                                        */
351
/*    Status                                Completion status             */
352
/*                                                                        */
353
/*  CALLS                                                                 */
354
/*                                                                        */
355
/*    _gx_binres_language_table_buffer_allocate                           */
356
/*                                          Allocate needed buffer for    */
357
/*                                            loading language table      */
358
/*    _gx_binres_resource_header_load                                     */
359
/*                                          Read resource header          */
360
/*    _gx_binres_string_header_load         Read string data header       */
361
/*    _gx_binres_language_header_load       Read language data header     */
362
/*    _gx_system_memory_free                Application defined memory    */
363
/*                                            free function               */
364
/*                                                                        */
365
/*  CALLED BY                                                             */
366
/*                                                                        */
367
/*    Application Code                                                    */
368
/*                                                                        */
369
/*  RELEASE HISTORY                                                       */
370
/*                                                                        */
371
/*    DATE              NAME                      DESCRIPTION             */
372
/*                                                                        */
373
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
374
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
375
/*                                            removed use of memcpy,      */
376
/*                                            resulting in version 6.1    */
377
/*                                                                        */
378
/**************************************************************************/
379
#ifdef GX_BINARY_RESOURCE_SUPPORT
380
#ifdef GX_ENABLE_DEPRECATED_STRING_API
381
12
UINT _gx_binres_language_table_load(GX_UBYTE *root_address, GX_UBYTE ****returned_language_table)
382
{
383
UINT                status;
384
GX_BINRES_DATA_INFO info;
385
GX_RESOURCE_HEADER  header;
386
GX_STRING_HEADER    string_header;
387
GX_LANGUAGE_HEADER  language_header;
388
GX_UBYTE         ***language_table;
389
UINT                lang_index;
390
UINT                string_index;
391
USHORT              string_length;
392
GX_CHAR             get_char;
393
394
12
    memset(&info, 0, sizeof(GX_BINRES_DATA_INFO));
395
396
12
    info.gx_binres_root_address = root_address;
397
398
    /* Allocate memory that needed for language table.  */
399
12
    status = _gx_binres_language_table_buffer_allocate(&info, sizeof(GX_UBYTE * *), sizeof(GX_UBYTE *));
400
401
    /* Read Resource header. */
402
12
    info.gx_binres_read_offset = 0;
403
12
    _gx_binres_resource_header_load(&info, &header);
404
405
    /* Skip theme info.  */
406
12
    info.gx_binres_read_offset += header.gx_resource_header_theme_data_size;
407
408
12
    if (header.gx_resource_header_magic_number != GX_MAGIC_NUMBER)
409
    {
410
1
        return GX_INVALID_FORMAT;
411
    }
412
413
11
    language_table = GX_NULL;
414
415
    /* Read language table.  */
416
11
    if (status == GX_SUCCESS)
417
    {
418
        /* Read string header. */
419
6
        _gx_binres_string_header_load(&info, &string_header);
420
421
6
        language_table = (GX_UBYTE ***)(info.gx_binres_buffer + info.gx_binres_buffer_index);
422
6
        info.gx_binres_buffer_index += sizeof(GX_UBYTE * *) * string_header.gx_string_header_language_count;
423
424
11
        for (lang_index = 0; lang_index < string_header.gx_string_header_language_count; lang_index++)
425
        {
426
            /* Read language header.  */
427
6
            _gx_binres_language_header_load(&info, &language_header);
428
429
6
            if (language_header.gx_language_header_magic_number != GX_MAGIC_NUMBER)
430
            {
431
1
                status = GX_INVALID_FORMAT;
432
1
                break;
433
            }
434
435
            /* Read string table.  */
436
5
            language_table[lang_index] = (GX_UBYTE **)(info.gx_binres_buffer + info.gx_binres_buffer_index);
437
5
            info.gx_binres_buffer_index += sizeof(GX_UBYTE *) * string_header.gx_string_header_string_count;
438
439
5
            if (header.gx_resource_header_version >= GX_BINRES_VERSION_ADD_STRING_LENGTH)
440
            {
441
72
                for (string_index = 1; string_index < string_header.gx_string_header_string_count; string_index++)
442
                {
443
                    /* Read string length. */
444
68
                    GX_BINRES_READ_USHORT(string_length, info.gx_binres_root_address + info.gx_binres_read_offset);
445
68
                    info.gx_binres_read_offset += sizeof(USHORT);
446
447
68
                    if (string_length == 0)
448
                    {
449
20
                        language_table[lang_index][string_index] = GX_NULL;
450
                    }
451
                    else
452
                    {
453
48
                        language_table[lang_index][string_index] = (GX_UBYTE *)(info.gx_binres_root_address + info.gx_binres_read_offset);
454
48
                        info.gx_binres_read_offset += (UINT)(string_length + 1);
455
                    }
456
                }
457
            }
458
            else
459
            {
460
1
                string_index = 1;
461
1
                string_length = 0;
462
131
                while (string_index < string_header.gx_string_header_string_count)
463
                {
464
130
                    string_length++;
465
466
130
                    get_char = (GX_CHAR)info.gx_binres_root_address[info.gx_binres_read_offset];
467
130
                    info.gx_binres_read_offset++;
468
469
130
                    if (get_char == '\0')
470
                    {
471
17
                        if (string_length == 1)
472
                        {
473
5
                            language_table[lang_index][string_index] = GX_NULL;
474
                        }
475
                        else
476
                        {
477
12
                            language_table[lang_index][string_index] = (GX_UBYTE *)(info.gx_binres_root_address + info.gx_binres_read_offset - string_length);
478
                        }
479
480
17
                        string_length = 0;
481
17
                        string_index++;
482
                    }
483
                }
484
            }
485
        }
486
    }
487
488
11
    if (status == GX_SUCCESS)
489
    {
490
5
        *returned_language_table = language_table;
491
    }
492
    else
493
    {
494
        /* Free allocated memory when language loading failed. */
495
6
        if (info.gx_binres_buffer)
496
        {
497
1
            _gx_system_memory_free(info.gx_binres_buffer);
498
        }
499
500
6
        *returned_language_table = GX_NULL;
501
    }
502
503
504
11
    return status;
505
}
506
#endif
507
#endif
508
509
/**************************************************************************/
510
/*                                                                        */
511
/*  FUNCTION                                               RELEASE        */
512
/*                                                                        */
513
/*    _gx_binres_language_table_load_ext                  PORTABLE C      */
514
/*                                                           6.1          */
515
/*  AUTHOR                                                                */
516
/*                                                                        */
517
/*    Kenneth Maxwell, Microsoft Corporation                              */
518
/*                                                                        */
519
/*  DESCRIPTION                                                           */
520
/*                                                                        */
521
/*    This service loads a language table from a binary data buffer.      */
522
/*                                                                        */
523
/*  INPUT                                                                 */
524
/*                                                                        */
525
/*    root_address                          Root address of binary        */
526
/*                                            resource data               */
527
/*    returned_language_table               Pointer to loaded language    */
528
/*                                           table                        */
529
/*                                                                        */
530
/*  OUTPUT                                                                */
531
/*                                                                        */
532
/*    Status                                Completion status             */
533
/*                                                                        */
534
/*  CALLS                                                                 */
535
/*                                                                        */
536
/*    _gx_binres_language_table_buffer_allocate                           */
537
/*                                          Allocate needed buffer for    */
538
/*                                            loading language table      */
539
/*    _gx_binres_resource_header_load                                     */
540
/*                                          Read resource header          */
541
/*    _gx_binres_string_header_load         Read string data header       */
542
/*    _gx_binres_language_header_load       Read language data header     */
543
/*    _gx_system_memory_free                Application defined memory    */
544
/*                                            free function               */
545
/*                                                                        */
546
/*  CALLED BY                                                             */
547
/*                                                                        */
548
/*    Application Code                                                    */
549
/*                                                                        */
550
/*  RELEASE HISTORY                                                       */
551
/*                                                                        */
552
/*    DATE              NAME                      DESCRIPTION             */
553
/*                                                                        */
554
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
555
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
556
/*                                            resulting in version 6.1    */
557
/*                                                                        */
558
/**************************************************************************/
559
#ifdef GX_BINARY_RESOURCE_SUPPORT
560
34
UINT _gx_binres_language_table_load_ext(GX_UBYTE *root_address, GX_STRING ***returned_language_table)
561
{
562
UINT                status;
563
GX_BINRES_DATA_INFO info;
564
GX_RESOURCE_HEADER  header;
565
GX_STRING_HEADER    string_header;
566
GX_LANGUAGE_HEADER  language_header;
567
GX_STRING         **language_table;
568
UINT                lang_index;
569
UINT                string_index;
570
USHORT              string_length;
571
GX_UBYTE           *get_data;
572
573
34
    memset(&info, 0, sizeof(GX_BINRES_DATA_INFO));
574
575
34
    info.gx_binres_root_address = root_address;
576
577
    /* Allocate memory that needed for language table.  */
578
34
    status = _gx_binres_language_table_buffer_allocate(&info, sizeof(GX_STRING *), sizeof(GX_STRING));
579
580
    /* Read Resource header. */
581
34
    info.gx_binres_read_offset = 0;
582
34
    _gx_binres_resource_header_load(&info, &header);
583
584
    /* Skip theme info.  */
585
34
    info.gx_binres_read_offset += header.gx_resource_header_theme_data_size;
586
587
34
    if (header.gx_resource_header_magic_number != GX_MAGIC_NUMBER)
588
    {
589
1
        return GX_INVALID_FORMAT;
590
    }
591
592
33
    language_table = GX_NULL;
593
594
    /* Read language table.  */
595
33
    if (status == GX_SUCCESS)
596
    {
597
        /* Read string header. */
598
28
        _gx_binres_string_header_load(&info, &string_header);
599
600
28
        language_table = (GX_STRING **)(info.gx_binres_buffer + info.gx_binres_buffer_index);
601
28
        info.gx_binres_buffer_index += sizeof(GX_STRING *) * string_header.gx_string_header_language_count;
602
603
55
        for (lang_index = 0; lang_index < string_header.gx_string_header_language_count; lang_index++)
604
        {
605
            /* Read language header.  */
606
28
            _gx_binres_language_header_load(&info, &language_header);
607
608
28
            if (language_header.gx_language_header_magic_number != GX_MAGIC_NUMBER)
609
            {
610
1
                status = GX_INVALID_FORMAT;
611
1
                break;
612
            }
613
614
            /* Read string table.  */
615
27
            language_table[lang_index] = (GX_STRING *)(info.gx_binres_buffer + info.gx_binres_buffer_index);
616
27
            info.gx_binres_buffer_index += sizeof(GX_STRING) * string_header.gx_string_header_string_count;
617
618
2176
            for (string_index = 1; string_index < string_header.gx_string_header_string_count; string_index++)
619
            {
620
                /* Read string length. */
621
2149
                get_data = info.gx_binres_root_address + info.gx_binres_read_offset;
622
2149
                string_length = *(get_data + 1);
623
2149
                string_length = (USHORT)(string_length << 8);
624
2149
                string_length = (USHORT)(string_length | (*get_data));
625
2149
                info.gx_binres_read_offset += sizeof(USHORT);
626
627
2149
                if (string_length)
628
                {
629
2098
                    language_table[lang_index][string_index].gx_string_ptr = (GX_CHAR *)(info.gx_binres_root_address + info.gx_binres_read_offset);
630
                }
631
                else
632
                {
633
51
                    language_table[lang_index][string_index].gx_string_ptr = GX_NULL;
634
                }
635
636
2149
                language_table[lang_index][string_index].gx_string_length = string_length;
637
2149
                info.gx_binres_read_offset += (UINT)(string_length + 1);
638
            }
639
        }
640
    }
641
642
33
    if (status == GX_SUCCESS)
643
    {
644
27
        *returned_language_table = language_table;
645
    }
646
    else
647
    {
648
        /* Free allocated memory when language loading failed. */
649
6
        if (info.gx_binres_buffer)
650
        {
651
1
            _gx_system_memory_free(info.gx_binres_buffer);
652
        }
653
654
6
        *returned_language_table = GX_NULL;
655
    }
656
657
658
33
    return status;
659
}
660
#endif
661