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 /** ThreadX Component                                                     */
16 /**                                                                       */
17 /**   Module Manager                                                      */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define TX_SOURCE_CODE
23 
24 #include "tx_api.h"
25 #include "tx_initialize.h"
26 #include "tx_thread.h"
27 #include "tx_timer.h"
28 #include "tx_queue.h"
29 #include "tx_event_flags.h"
30 #include "tx_semaphore.h"
31 #include "tx_mutex.h"
32 #include "tx_block_pool.h"
33 #include "tx_byte_pool.h"
34 #include "txm_module.h"
35 #include "txm_module_manager_util.h"
36 
37 
38 /**************************************************************************/
39 /*                                                                        */
40 /*  FUNCTION                                               RELEASE        */
41 /*                                                                        */
42 /*    _txm_module_manager_object_pointer_get_extended     PORTABLE C      */
43 /*                                                           6.1          */
44 /*  AUTHOR                                                                */
45 /*                                                                        */
46 /*    Scott Larson, Microsoft Corporation                                 */
47 /*                                                                        */
48 /*  DESCRIPTION                                                           */
49 /*                                                                        */
50 /*    This function retrieves the object pointer of a particular type     */
51 /*    with a particular name. If the object is not found, an error is     */
52 /*    returned. Otherwise, if the object is found, the address of that    */
53 /*    object is placed in object_ptr.                                     */
54 /*                                                                        */
55 /*  INPUT                                                                 */
56 /*                                                                        */
57 /*    object_type                       Type of object, as follows:       */
58 /*                                                                        */
59 /*                                          TXM_BLOCK_POOL_OBJECT         */
60 /*                                          TXM_BYTE_POOL_OBJECT          */
61 /*                                          TXM_EVENT_FLAGS_OBJECT        */
62 /*                                          TXM_MUTEX_OBJECT              */
63 /*                                          TXM_QUEUE_OBJECT              */
64 /*                                          TXM_SEMAPHORE_OBJECT          */
65 /*                                          TXM_THREAD_OBJECT             */
66 /*                                          TXM_TIMER_OBJECT              */
67 /*    search_name                       Name to search for                */
68 /*    search_name_length                Length of the name excluding      */
69 /*                                        null-terminator                 */
70 /*    object_ptr                        Pointer to the object             */
71 /*                                                                        */
72 /*  OUTPUT                                                                */
73 /*                                                                        */
74 /*    TX_SUCCESS                        Successful completion             */
75 /*    TX_PTR_ERROR                      Invalid name or object ptr        */
76 /*    TX_OPTION_ERROR                   Invalid option type               */
77 /*    TX_NO_INSTANCE                    Object not found                  */
78 /*                                                                        */
79 /*  CALLS                                                                 */
80 /*                                                                        */
81 /*    _txm_module_manager_object_name_compare                             */
82 /*                                      String compare routine            */
83 /*    [_txm_module_manager_*_object_pointer_get]                          */
84 /*                                      Optional external component       */
85 /*                                        object pointer get              */
86 /*                                                                        */
87 /*  CALLED BY                                                             */
88 /*                                                                        */
89 /*    Application code                                                    */
90 /*                                                                        */
91 /*  RELEASE HISTORY                                                       */
92 /*                                                                        */
93 /*    DATE              NAME                      DESCRIPTION             */
94 /*                                                                        */
95 /*  09-30-2020      Scott Larson            Initial Version 6.1           */
96 /*                                                                        */
97 /**************************************************************************/
_txm_module_manager_object_pointer_get_extended(UINT object_type,CHAR * search_name,UINT search_name_length,VOID ** object_ptr)98 UINT  _txm_module_manager_object_pointer_get_extended(UINT object_type, CHAR *search_name, UINT search_name_length, VOID **object_ptr)
99 {
100 
101 TX_INTERRUPT_SAVE_AREA
102 
103 TX_THREAD               *thread_ptr;
104 TX_TIMER                *timer_ptr;
105 TX_QUEUE                *queue_ptr;
106 TX_EVENT_FLAGS_GROUP    *events_ptr;
107 TX_SEMAPHORE            *semaphore_ptr;
108 TX_MUTEX                *mutex_ptr;
109 TX_BLOCK_POOL           *block_pool_ptr;
110 TX_BYTE_POOL            *byte_pool_ptr;
111 ULONG                   i;
112 UINT                    status;
113 TXM_MODULE_INSTANCE     *module_instance;
114 
115 
116     /* Determine if the name or object pointer are NULL.  */
117     if ((search_name == TX_NULL) || (object_ptr == TX_NULL))
118     {
119 
120         /* Return error!  */
121         return(TX_PTR_ERROR);
122     }
123 
124     /* Default status to not found.  */
125     status =  TX_NO_INSTANCE;
126 
127     /* Set the return value to NULL.  */
128     *object_ptr =  TX_NULL;
129 
130     /* Disable interrupts.  */
131     TX_DISABLE
132 
133     /* Temporarily disable preemption.  This will keep other threads from creating and deleting threads.  */
134     _tx_thread_preempt_disable++;
135 
136     /* Restore interrupts.  */
137     TX_RESTORE
138 
139     /* Process relative to the object type.  */
140     switch(object_type)
141     {
142 
143     /* Determine if a thread object is requested.  */
144     case TXM_THREAD_OBJECT:
145     {
146 
147         /* Loop to find the first matching thread.  */
148         i = 0;
149         thread_ptr =  _tx_thread_created_ptr;
150         while (i < _tx_thread_created_count)
151         {
152 
153             /* Do we have a match?  */
154             if (_txm_module_manager_object_name_compare(search_name, search_name_length, thread_ptr -> tx_thread_name))
155             {
156 
157                 /* Yes, we found it - return the necessary info!  */
158                 *object_ptr =  (VOID *) thread_ptr;
159 
160                 /* Set the the status to success!  */
161                 status =  TX_SUCCESS;
162                 break;
163             }
164 
165             /* Increment the counter.  */
166             i++;
167 
168             /* Move to next thread.  */
169             thread_ptr =  thread_ptr -> tx_thread_created_next;
170         }
171         break;
172     }
173 
174     /* Determine if a timer object is requested.  */
175     case TXM_TIMER_OBJECT:
176     {
177 
178         /* Loop to find the first matching timer.  */
179         i = 0;
180         timer_ptr =  _tx_timer_created_ptr;
181         while (i < _tx_timer_created_count)
182         {
183 
184             /* Do we have a match?  */
185             if (_txm_module_manager_object_name_compare(search_name, search_name_length, timer_ptr -> tx_timer_name))
186             {
187 
188                 /* Yes, we found it - return the necessary info!  */
189                 *object_ptr =  (VOID *) timer_ptr;
190 
191                 /* Set the the status to success!  */
192                 status =  TX_SUCCESS;
193                 break;
194             }
195 
196             /* Increment the counter.  */
197             i++;
198 
199             /* Move to next timer.  */
200             timer_ptr =  timer_ptr -> tx_timer_created_next;
201         }
202         break;
203     }
204 
205     /* Determine if a queue object is requested.  */
206     case TXM_QUEUE_OBJECT:
207     {
208 
209         /* Loop to find the first matching queue.  */
210         i = 0;
211         queue_ptr =  _tx_queue_created_ptr;
212         while (i < _tx_queue_created_count)
213         {
214 
215             /* Do we have a match?  */
216             if (_txm_module_manager_object_name_compare(search_name, search_name_length, queue_ptr -> tx_queue_name))
217             {
218 
219                 /* Yes, we found it - return the necessary info!  */
220                 *object_ptr =  (VOID *) queue_ptr;
221 
222                 /* Set the the status to success!  */
223                 status =  TX_SUCCESS;
224                 break;
225             }
226 
227             /* Increment the counter.  */
228             i++;
229 
230             /* Move to next queue.  */
231             queue_ptr =  queue_ptr -> tx_queue_created_next;
232         }
233         break;
234     }
235 
236     /* Determine if a event flags object is requested.  */
237     case TXM_EVENT_FLAGS_OBJECT:
238     {
239 
240         /* Loop to find the first matching event flags group.  */
241         i = 0;
242         events_ptr =  _tx_event_flags_created_ptr;
243         while (i < _tx_event_flags_created_count)
244         {
245 
246             /* Do we have a match?  */
247             if (_txm_module_manager_object_name_compare(search_name, search_name_length, events_ptr -> tx_event_flags_group_name))
248             {
249 
250                 /* Yes, we found it - return the necessary info!  */
251                 *object_ptr =  (VOID *) events_ptr;
252 
253                 /* Set the the status to success!  */
254                 status =  TX_SUCCESS;
255                 break;
256             }
257 
258             /* Increment the counter.  */
259             i++;
260 
261             /* Move to next event flags group.  */
262             events_ptr =  events_ptr -> tx_event_flags_group_created_next;
263         }
264         break;
265     }
266 
267     /* Determine if a semaphore object is requested.  */
268     case TXM_SEMAPHORE_OBJECT:
269     {
270 
271         /* Loop to find the first matching semaphore.  */
272         i = 0;
273         semaphore_ptr =  _tx_semaphore_created_ptr;
274         while (i < _tx_semaphore_created_count)
275         {
276 
277             /* Do we have a match?  */
278             if (_txm_module_manager_object_name_compare(search_name, search_name_length, semaphore_ptr -> tx_semaphore_name))
279             {
280 
281                 /* Yes, we found it - return the necessary info!  */
282                 *object_ptr =  (VOID *) semaphore_ptr;
283 
284                 /* Set the the status to success!  */
285                 status =  TX_SUCCESS;
286                 break;
287             }
288 
289             /* Increment the counter.  */
290             i++;
291 
292             /* Move to next semaphore.  */
293             semaphore_ptr =  semaphore_ptr -> tx_semaphore_created_next;
294         }
295         break;
296     }
297 
298     /* Determine if a mutex object is requested.  */
299     case TXM_MUTEX_OBJECT:
300     {
301 
302         /* Loop to find the first matching mutex.  */
303         i = 0;
304         mutex_ptr =  _tx_mutex_created_ptr;
305         while (i < _tx_mutex_created_count)
306         {
307 
308             /* Do we have a match?  */
309             if (_txm_module_manager_object_name_compare(search_name, search_name_length, mutex_ptr -> tx_mutex_name))
310             {
311 
312                 /* Yes, we found it - return the necessary info!  */
313                 *object_ptr =  (VOID *) mutex_ptr;
314 
315                 /* Set the the status to success!  */
316                 status =  TX_SUCCESS;
317                 break;
318             }
319 
320             /* Increment the counter.  */
321             i++;
322 
323             /* Move to next mutex.  */
324             mutex_ptr =  mutex_ptr -> tx_mutex_created_next;
325         }
326         break;
327     }
328 
329     /* Determine if a block pool object is requested.  */
330     case TXM_BLOCK_POOL_OBJECT:
331     {
332 
333         /* Get the module instance.  */
334         module_instance =  _tx_thread_current_ptr -> tx_thread_module_instance_ptr;
335 
336         /* Is a module making this request?  */
337         if (module_instance != TX_NULL)
338         {
339 
340             /* Is memory protection enabled?  */
341             if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION)
342             {
343 
344                 /* Modules with memory protection can only access block pools they created.  */
345                 status =  TXM_MODULE_INVALID;
346                 break;
347             }
348         }
349 
350         /* Loop to find the first matching block pool.  */
351         i = 0;
352         block_pool_ptr =  _tx_block_pool_created_ptr;
353         while (i < _tx_block_pool_created_count)
354         {
355 
356             /* Do we have a match?  */
357             if (_txm_module_manager_object_name_compare(search_name, search_name_length, block_pool_ptr -> tx_block_pool_name))
358             {
359 
360                 /* Yes, we found it - return the necessary info!  */
361                 *object_ptr =  (VOID *) block_pool_ptr;
362 
363                 /* Set the the status to success!  */
364                 status =  TX_SUCCESS;
365                 break;
366             }
367 
368             /* Increment the counter.  */
369             i++;
370 
371             /* Move to next block pool.  */
372             block_pool_ptr =  block_pool_ptr -> tx_block_pool_created_next;
373         }
374         break;
375     }
376 
377     /* Determine if a byte pool object is requested.  */
378     case TXM_BYTE_POOL_OBJECT:
379     {
380 
381         /* Get the module instance.  */
382         module_instance =  _tx_thread_current_ptr -> tx_thread_module_instance_ptr;
383 
384         /* Is a module making this request?  */
385         if (module_instance != TX_NULL)
386         {
387 
388             /* Is memory protection enabled?  */
389             if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION)
390             {
391 
392                 /* Modules with memory protection can only access block pools they created.  */
393                 status =  TXM_MODULE_INVALID;
394                 break;
395             }
396         }
397 
398         /* Loop to find the first matching byte pool.  */
399         i = 0;
400         byte_pool_ptr =  _tx_byte_pool_created_ptr;
401         while (i < _tx_byte_pool_created_count)
402         {
403 
404             /* Do we have a match?  */
405             if (_txm_module_manager_object_name_compare(search_name, search_name_length, byte_pool_ptr -> tx_byte_pool_name))
406             {
407 
408                 /* Yes, we found it - return the necessary info!  */
409                 *object_ptr =  (VOID *) byte_pool_ptr;
410 
411                 /* Set the the status to success!  */
412                 status =  TX_SUCCESS;
413                 break;
414             }
415 
416             /* Increment the counter.  */
417             i++;
418 
419             /* Move to next byte pool.  */
420             byte_pool_ptr =  byte_pool_ptr -> tx_byte_pool_created_next;
421         }
422         break;
423     }
424 
425     default:
426 
427         /* Invalid object ID.  */
428         status =  TX_OPTION_ERROR;
429 
430         /* External Object pointer get.  */
431 
432 #ifdef TXM_MODULE_ENABLE_NETX
433 
434         /* Determine if there is a NetX object get request.  */
435         if ((object_type >= TXM_NETX_OBJECTS_START) && (object_type < TXM_NETX_OBJECTS_END))
436         {
437 
438             /* Call the NetX module object get function.  */
439             status =  _txm_module_manager_netx_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
440         }
441 #endif
442 
443 #ifdef TXM_MODULE_ENABLE_NETXDUO
444 
445         /* Determine if there is a NetX Duo object get request.  */
446         if ((object_type >= TXM_NETXDUO_OBJECTS_START) && (object_type < TXM_NETXDUO_OBJECTS_END))
447         {
448 
449             /* Call the NetX Duo module object get function.  */
450             status =  _txm_module_manager_netxduo_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
451         }
452 #endif
453 
454 #ifdef TXM_MODULE_ENABLE_FILEX
455 
456         /* Determine if there is a FileX object get request.  */
457         if ((object_type >= TXM_FILEX_OBJECTS_START) && (object_type < TXM_FILEX_OBJECTS_END))
458         {
459 
460             /* Call the FileX module object get function.  */
461             status =  _txm_module_manager_filex_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
462         }
463 #endif
464 
465 
466 #ifdef TXM_MODULE_ENABLE_GUIX
467 
468         /* Determine if there is a GUIX object get request.  */
469         if ((object_type >= TXM_GUIX_OBJECTS_START) && (object_type < TXM_GUIX_OBJECTS_END))
470         {
471 
472             /* Call the GUIX module object get function.  */
473             status =  _txm_module_manager_guix_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
474         }
475 #endif
476 
477 #ifdef TXM_MODULE_ENABLE_USBX
478 
479         /* Determine if there is a USBX object get request.  */
480         if ((object_type >= TXM_USBX_OBJECTS_START) && (object_type < TXM_USBX_OBJECTS_END))
481         {
482 
483             /* Call the USBX object get function.  */
484             status =  _txm_module_manager_usbx_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
485         }
486 #endif
487 
488         break;
489     }
490 
491     /* Disable interrupts.  */
492     TX_DISABLE
493 
494     /* Enable preemption again.  */
495     _tx_thread_preempt_disable--;
496 
497     /* Restore interrupts.  */
498     TX_RESTORE
499 
500     /* Check for preemption.  */
501     _tx_thread_system_preempt_check();
502 
503     /* Return success.  */
504     return(status);
505 }
506