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