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 /** Prompt Management (Prompt) */
19 /** */
20 /**************************************************************************/
21
22 #define GX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26 #include "gx_api.h"
27 #include "gx_system.h"
28 #include "gx_utility.h"
29
30 /**************************************************************************/
31 /* */
32 /* FUNCTION RELEASE */
33 /* */
34 /* _gx_system_private_string_copy PORTABLE C */
35 /* 6.1 */
36 /* AUTHOR */
37 /* */
38 /* Kenneth Maxwell, Microsoft Corporation */
39 /* */
40 /* DESCRIPTION */
41 /* */
42 /* This service makes a private copy of text assigned to a widget. */
43 /* */
44 /* */
45 /* INPUT */
46 /* */
47 /* string Address of widget's text */
48 /* pointer */
49 /* text Pointer to string */
50 /* */
51 /* OUTPUT */
52 /* */
53 /* status Completion status */
54 /* */
55 /* CALLS */
56 /* */
57 /* _gx_utility_string_length_check Test string length */
58 /* _gx_system_memory_allocator Allocate dynamic memory */
59 /* _gx_system_memory_free Deallocate dynamic memory */
60 /* */
61 /* CALLED BY */
62 /* */
63 /* GUIX internal code */
64 /* */
65 /* RELEASE HISTORY */
66 /* */
67 /* DATE NAME DESCRIPTION */
68 /* */
69 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
70 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
71 /* resulting in version 6.1 */
72 /* */
73 /**************************************************************************/
_gx_system_private_string_copy(GX_STRING * string,GX_CONST GX_STRING * text)74 UINT _gx_system_private_string_copy(GX_STRING *string, GX_CONST GX_STRING *text)
75 {
76 GX_UBYTE *byte;
77 USHORT current_buffer_size;
78 USHORT needed_buffer_size;
79
80 if (_gx_system_memory_allocator == GX_NULL)
81 {
82 string -> gx_string_ptr = GX_NULL;
83 string -> gx_string_length = 0;
84 return GX_SYSTEM_MEMORY_ERROR;
85 }
86
87 /* are we assigning a non-NULL string? */
88 if (text && text -> gx_string_ptr)
89 {
90 GX_UTILITY_USHORT_CHECK(text -> gx_string_length)
91 GX_UTILITY_MATH_USHORT_ADD((USHORT)text -> gx_string_length, 3, needed_buffer_size)
92 }
93 else
94 {
95 needed_buffer_size = 0;
96 }
97
98 if (needed_buffer_size)
99 {
100 /* check to see if we have already allocated sufficient memory */
101 if (string -> gx_string_ptr)
102 {
103 byte = (GX_UBYTE *)string -> gx_string_ptr;
104 current_buffer_size = *byte++;
105 current_buffer_size = (USHORT)(current_buffer_size << 8);
106 current_buffer_size = (USHORT)(current_buffer_size | (*byte++));
107
108 if (current_buffer_size < needed_buffer_size)
109 {
110 /* if our buffer is not large enough, free the current buffer */
111 _gx_system_memory_free((void *)string -> gx_string_ptr);
112
113 /* and attempt to allocate a new buffer */
114 string -> gx_string_ptr = (GX_CHAR *)_gx_system_memory_allocator(needed_buffer_size);
115
116 /* if buffer allocation succeeded, update our buffer size and copy the string */
117 if (string -> gx_string_ptr)
118 {
119 byte = (GX_UBYTE *)string -> gx_string_ptr;
120 *byte++ = (GX_UBYTE)(needed_buffer_size >> 8);
121 *byte++ = (GX_UBYTE)(needed_buffer_size & 0xff);
122
123 memcpy(byte, text -> gx_string_ptr, text -> gx_string_length + 1); /* Use case of memcpy is verified. */
124 string -> gx_string_length = text -> gx_string_length;
125 }
126 else
127 {
128 string -> gx_string_length = 0;
129 }
130 }
131 else
132 {
133 /* the existing buffer is large enough, just copy the string without updating buffer size */
134 memcpy(byte, text -> gx_string_ptr, text -> gx_string_length + 1); /* Use case of memcpy is verified. */
135 string -> gx_string_length = text -> gx_string_length;
136 }
137 }
138 else
139 {
140 /* the current buffer is NULL, attempt to allocate a new buffer */
141 string -> gx_string_ptr = (GX_CHAR *)_gx_system_memory_allocator(needed_buffer_size);
142
143 /* if buffer allocation succeeded, update our buffer size and copy the string */
144 if (string -> gx_string_ptr)
145 {
146 byte = (GX_UBYTE *)string -> gx_string_ptr;
147 *byte++ = (GX_UBYTE)(needed_buffer_size >> 8);
148 *byte++ = (GX_UBYTE)(needed_buffer_size & 0xff);
149
150 memcpy(byte, text -> gx_string_ptr, text -> gx_string_length + 1); /* Use case of memcpy is verified. */
151 string -> gx_string_length = text -> gx_string_length;
152 }
153 else
154 {
155 string -> gx_string_length = 0;
156 }
157 }
158 }
159 else
160 {
161 /* here if the new text is GX_NULL, free our buffer if one has been allocated */
162 if (string -> gx_string_ptr)
163 {
164 _gx_system_memory_free((void *)string -> gx_string_ptr);
165 string -> gx_string_ptr = GX_NULL;
166 }
167
168 string -> gx_string_length = 0;
169 return GX_SUCCESS;
170 }
171 if (string -> gx_string_ptr)
172 {
173 return(GX_SUCCESS);
174 }
175 return GX_SYSTEM_MEMORY_ERROR;
176 }
177
178 /**************************************************************************/
179 /* */
180 /* FUNCTION RELEASE */
181 /* */
182 /* _gx_system_private_string_list_copy PORTABLE C */
183 /* 6.1 */
184 /* AUTHOR */
185 /* */
186 /* Kenneth Maxwell, Microsoft Corporation */
187 /* */
188 /* DESCRIPTION */
189 /* */
190 /* This service makes a private copy of string list assigned to a */
191 /* widget. */
192 /* */
193 /* */
194 /* INPUT */
195 /* */
196 /* ptr_address Address of widget's string */
197 /* list pointer */
198 /* string_list Pointer to string list */
199 /* string_count Number of string in list */
200 /* */
201 /* OUTPUT */
202 /* */
203 /* status Completion status */
204 /* */
205 /* CALLS */
206 /* */
207 /* _gx_utility_string_length_check Test string length */
208 /* _gx_system_memory_allocator Allocate dynamic memory */
209 /* _gx_system_memory_free Deallocate dynamic memory */
210 /* */
211 /* CALLED BY */
212 /* */
213 /* GUIX internal code */
214 /* */
215 /* RELEASE HISTORY */
216 /* */
217 /* DATE NAME DESCRIPTION */
218 /* */
219 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
220 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
221 /* resulting in version 6.1 */
222 /* */
223 /**************************************************************************/
224 #if defined(GX_ENABLE_DEPRECATED_STRING_API)
_gx_system_private_string_list_copy(GX_CONST GX_CHAR *** ptr_address,GX_CONST GX_CHAR ** string_list,INT string_count)225 UINT _gx_system_private_string_list_copy(GX_CONST GX_CHAR ***ptr_address, GX_CONST GX_CHAR **string_list, INT string_count)
226 {
227 UINT status;
228 GX_UBYTE *byte;
229 USHORT current_buffer_size;
230 USHORT needed_buffer_size;
231 INT index;
232 GX_CHAR **list_ptr;
233 GX_CHAR *string_ptr;
234 UINT length;
235
236 list_ptr = (GX_CHAR **)*ptr_address;
237
238 if (_gx_system_memory_allocator == GX_NULL)
239 {
240 *ptr_address = GX_NULL;
241 return GX_SYSTEM_MEMORY_ERROR;
242 }
243
244 /* are we assigning a non-NULL string array? */
245 if (string_list)
246 {
247 /* calculate size of needed buffer. buffer size for holding each string pointer +
248 2 byte size +
249 buffer size of each string. */
250 GX_UTILITY_USHORT_CHECK(string_count)
251 GX_UTILITY_MATH_USHORT_MULT((USHORT)string_count, sizeof(GX_CHAR *), needed_buffer_size)
252
253 /* As string_count is an integer, the maximum needed_buffer_size is 65532,
254 so that needed_buffer_size can not be overflow. */
255 needed_buffer_size = (USHORT)(needed_buffer_size + 2);
256
257 for (index = 0; index < string_count; index++)
258 {
259 if (string_list[index])
260 {
261 status = _gx_utility_string_length_check(string_list[index], &length, GX_MAX_STRING_LENGTH);
262
263 if (status != GX_SUCCESS)
264 {
265 return status;
266 }
267
268 GX_UTILITY_USHORT_CHECK(length)
269 GX_UTILITY_MATH_USHORT_ADD(needed_buffer_size, (USHORT)length, needed_buffer_size)
270 GX_UTILITY_MATH_USHORT_ADD(needed_buffer_size, 1, needed_buffer_size)
271 }
272 }
273 }
274 else
275 {
276 needed_buffer_size = 0;
277 }
278
279 if (needed_buffer_size)
280 {
281 /* check to see if we have already allocated sufficient memory */
282 if (list_ptr)
283 {
284 byte = (GX_UBYTE *)list_ptr;
285 current_buffer_size = *byte++;
286 current_buffer_size = (USHORT)(current_buffer_size << 8);
287 current_buffer_size = (USHORT)(current_buffer_size | (*byte++));
288
289 if (current_buffer_size < needed_buffer_size)
290 {
291 /* if our buffer is not large enough, free the current buffer */
292 _gx_system_memory_free((void *)list_ptr);
293
294 /* and attempt to allocate a new buffer */
295 list_ptr = (GX_CHAR **)_gx_system_memory_allocator(needed_buffer_size);
296 }
297 }
298 else
299 {
300 /* the current buffer is NULL, attempt to allocate a new buffer */
301 list_ptr = (GX_CHAR **)_gx_system_memory_allocator(needed_buffer_size);
302 }
303
304 if (list_ptr)
305 {
306 *ptr_address = (GX_CONST GX_CHAR **)list_ptr;
307 byte = (GX_UBYTE *)list_ptr;
308 *byte++ = (GX_UBYTE)(needed_buffer_size >> 8);
309 *byte++ = (GX_UBYTE)(needed_buffer_size & 0xff);
310
311 list_ptr = (GX_CHAR **)byte;
312 string_ptr = (GX_CHAR *)(byte + ((INT)sizeof(GX_CHAR *)) * string_count);
313
314 for (index = 0; index < string_count; index++)
315 {
316 list_ptr[index] = string_ptr;
317
318 if (string_list[index])
319 {
320 /* Get string length. */
321 _gx_utility_string_length_check(string_list[index], &length, GX_MAX_STRING_LENGTH);
322
323 memcpy((VOID *)string_ptr, string_list[index], length + 1); /* Use case of memcpy is verified. */
324 }
325 else
326 {
327 *string_ptr = '\0';
328 length = 0;
329 }
330
331 string_ptr += length + 1;
332 }
333 }
334 }
335 else
336 {
337 /* here if the new text is GX_NULL, free our buffer if one has been allocated */
338 if (list_ptr)
339 {
340 _gx_system_memory_free((void *)list_ptr);
341 *ptr_address = GX_NULL;
342 }
343 return GX_SUCCESS;
344 }
345 if (list_ptr)
346 {
347 return(GX_SUCCESS);
348 }
349 return GX_SYSTEM_MEMORY_ERROR;
350 }
351 #endif
352
353 /**************************************************************************/
354 /* */
355 /* FUNCTION RELEASE */
356 /* */
357 /* _gx_system_private_string_list_copy_ext PORTABLE C */
358 /* 6.1 */
359 /* AUTHOR */
360 /* */
361 /* Kenneth Maxwell, Microsoft Corporation */
362 /* */
363 /* DESCRIPTION */
364 /* */
365 /* This service makes a private copy of string list assigned to a */
366 /* widget. */
367 /* */
368 /* */
369 /* INPUT */
370 /* */
371 /* ptr_address Address of widget's string */
372 /* list pointer */
373 /* buffer_size String list buffer size */
374 /* string_list Pointer to string list */
375 /* string_count Number of string in list */
376 /* */
377 /* OUTPUT */
378 /* */
379 /* status Completion status */
380 /* */
381 /* CALLS */
382 /* */
383 /* _gx_system_memory_allocator Allocate dynamic memory */
384 /* _gx_system_memory_free Deallocate dynamic memory */
385 /* */
386 /* CALLED BY */
387 /* */
388 /* GUIX internal code */
389 /* */
390 /* RELEASE HISTORY */
391 /* */
392 /* DATE NAME DESCRIPTION */
393 /* */
394 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
395 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
396 /* resulting in version 6.1 */
397 /* */
398 /**************************************************************************/
_gx_system_private_string_list_copy_ext(GX_STRING ** ptr_address,USHORT * buffer_size,GX_CONST GX_STRING * string_list,INT string_count)399 UINT _gx_system_private_string_list_copy_ext(GX_STRING **ptr_address, USHORT *buffer_size, GX_CONST GX_STRING *string_list, INT string_count)
400 {
401 USHORT current_buffer_size;
402 USHORT needed_buffer_size;
403 INT index;
404 GX_STRING *list_ptr;
405 GX_CONST GX_CHAR *string_ptr;
406 UINT length;
407
408 list_ptr = *ptr_address;
409
410 if (_gx_system_memory_allocator == GX_NULL)
411 {
412 return GX_SYSTEM_MEMORY_ERROR;
413 }
414
415 /* are we assigning a non-NULL string array? */
416 if (string_list)
417 {
418 /* calculate size of needed buffer. buffer size for holding each string pointer +
419 buffer size of each string. */
420 needed_buffer_size = (USHORT)(((INT)sizeof(GX_STRING)) * string_count);
421 for (index = 0; index < string_count; index++)
422 {
423 if (string_list[index].gx_string_ptr)
424 {
425 GX_UTILITY_USHORT_CHECK(string_list[index].gx_string_length)
426 GX_UTILITY_MATH_USHORT_ADD(needed_buffer_size, (USHORT)string_list[index].gx_string_length, needed_buffer_size)
427 GX_UTILITY_MATH_USHORT_ADD(needed_buffer_size, 1, needed_buffer_size)
428 }
429 }
430 }
431 else
432 {
433 needed_buffer_size = 0;
434 }
435
436 if (needed_buffer_size)
437 {
438 /* check to see if we have already allocated sufficient memory */
439 if (list_ptr)
440 {
441 current_buffer_size = *buffer_size;
442
443 if (current_buffer_size < needed_buffer_size)
444 {
445 /* if our buffer is not large enough, free the current buffer */
446 _gx_system_memory_free((void *)list_ptr);
447
448 /* and attempt to allocate a new buffer */
449 list_ptr = (GX_STRING *)_gx_system_memory_allocator(needed_buffer_size);
450 *buffer_size = needed_buffer_size;
451 }
452 }
453 else
454 {
455 /* the current buffer is NULL, attempt to allocate a new buffer */
456 list_ptr = (GX_STRING *)_gx_system_memory_allocator(needed_buffer_size);
457 *buffer_size = needed_buffer_size;
458 }
459
460 if (list_ptr)
461 {
462 *ptr_address = list_ptr;
463
464 string_ptr = (GX_CONST GX_CHAR *)(list_ptr + string_count);
465
466 for (index = 0; index < string_count; index++)
467 {
468 length = string_list[index].gx_string_length;
469
470 list_ptr[index].gx_string_ptr = string_ptr;
471 list_ptr[index].gx_string_length = length;
472
473 if (string_list[index].gx_string_ptr)
474 {
475 memcpy((VOID *)string_ptr, string_list[index].gx_string_ptr, length + 1); /* Use case of memcpy is verified. */
476 string_ptr += length + 1;
477 }
478 }
479 }
480 }
481 else
482 {
483 /* here if the new text is GX_NULL, free our buffer if one has been allocated */
484 if (list_ptr)
485 {
486 _gx_system_memory_free((void *)list_ptr);
487 *ptr_address = GX_NULL;
488 *buffer_size = 0;
489 }
490 return GX_SUCCESS;
491 }
492 if (list_ptr)
493 {
494 return(GX_SUCCESS);
495 }
496
497 return GX_SYSTEM_MEMORY_ERROR;
498 }
499
500 /**************************************************************************/
501 /* */
502 /* FUNCTION RELEASE */
503 /* */
504 /* _gx_system_private_string_get PORTABLE C */
505 /* 6.1 */
506 /* AUTHOR */
507 /* */
508 /* Kenneth Maxwell, Microsoft Corporation */
509 /* */
510 /* DESCRIPTION */
511 /* */
512 /* This service returns the string pointer in a dynamically copied */
513 /* string buffer. */
514 /* */
515 /* */
516 /* INPUT */
517 /* */
518 /* buffer string buffer address */
519 /* style calling widget style */
520 /* */
521 /* OUTPUT */
522 /* */
523 /* None */
524 /* */
525 /* CALLS */
526 /* */
527 /* */
528 /* CALLED BY */
529 /* */
530 /* _gx_checkbox_draw */
531 /* */
532 /* RELEASE HISTORY */
533 /* */
534 /* DATE NAME DESCRIPTION */
535 /* */
536 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
537 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
538 /* resulting in version 6.1 */
539 /* */
540 /**************************************************************************/
_gx_system_private_string_get(GX_CONST GX_STRING * input,GX_STRING * output,ULONG style)541 VOID _gx_system_private_string_get(GX_CONST GX_STRING *input, GX_STRING *output, ULONG style)
542 {
543 GX_UBYTE *temp;
544
545 output -> gx_string_ptr = GX_NULL;
546 output -> gx_string_length = 0;
547
548 if (input -> gx_string_ptr == GX_NULL)
549 {
550 return;
551 }
552
553 if (style & GX_STYLE_TEXT_COPY)
554 {
555 /* If the string has been dynamically copied, then the first two bytes of
556 the string buffer hold the buffer size. Skip those bytes and return
557 pointer to the actual string
558 */
559 temp = (GX_UBYTE *)input -> gx_string_ptr;
560 temp += 2;
561 output -> gx_string_ptr = (GX_CHAR *)temp;
562 output -> gx_string_length = input -> gx_string_length;
563 }
564 else
565 {
566 /* No dynamic copy, the buffer is the string */
567 output -> gx_string_ptr = input -> gx_string_ptr;
568 output -> gx_string_length = input -> gx_string_length;
569 }
570 }
571
572 /**************************************************************************/
573 /* */
574 /* FUNCTION RELEASE */
575 /* */
576 /* _gx_system_private_string_list_get PORTABLE C */
577 /* 6.1 */
578 /* AUTHOR */
579 /* */
580 /* Kenneth Maxwell, Microsoft Corporation */
581 /* */
582 /* DESCRIPTION */
583 /* */
584 /* This service returns the string pointer in a dynamically copied */
585 /* string buffer. */
586 /* */
587 /* */
588 /* INPUT */
589 /* */
590 /* buffer string buffer address */
591 /* style calling widget style */
592 /* */
593 /* OUTPUT */
594 /* */
595 /* None */
596 /* */
597 /* CALLS */
598 /* */
599 /* */
600 /* CALLED BY */
601 /* */
602 /* _gx_checkbox_draw */
603 /* */
604 /* RELEASE HISTORY */
605 /* */
606 /* DATE NAME DESCRIPTION */
607 /* */
608 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
609 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
610 /* resulting in version 6.1 */
611 /* */
612 /**************************************************************************/
613 #if defined(GX_ENABLE_DEPRECATED_STRING_API)
_gx_system_private_string_list_get(GX_CONST GX_CHAR ** input,GX_CONST GX_CHAR *** output,ULONG style)614 VOID _gx_system_private_string_list_get(GX_CONST GX_CHAR **input, GX_CONST GX_CHAR ***output, ULONG style)
615 {
616 GX_UBYTE *temp;
617
618 if (style & GX_STYLE_TEXT_COPY)
619 {
620 /* If the string has been dynamically copied, then the first two bytes of
621 the string buffer hold the buffer size. Skip those bytes and return
622 pointer to the actual string
623 */
624 temp = (GX_UBYTE *)input;
625 temp += 2;
626
627 *output = (GX_CONST GX_CHAR **)temp;
628 }
629 else
630 {
631 *output = input;
632 }
633 }
634 #endif
635
636