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