|
23 | 23 | #define DMDEVFS_CONTEXT_MAGIC 0x444D4456 // 'DMDV' |
24 | 24 | #define ROOT_DIRECTORY_NAME "/" |
25 | 25 | #define MAX_PATH_LENGTH (DMOD_MAX_MODULE_NAME_LENGTH + 20) |
| 26 | +#define INI_LINE_BUFFER_SIZE 256 |
| 27 | +#define INI_MAIN_SECTION "main" |
26 | 28 |
|
27 | 29 | /** |
28 | 30 | * @brief Type definition for path strings |
@@ -73,6 +75,7 @@ struct dmfsi_context |
73 | 75 | // ============================================================================ |
74 | 76 | static int configure_drivers(dmfsi_context_t ctx, const char* driver_name, const char* config_path); |
75 | 77 | static driver_node_t* configure_driver(const char* driver_name, dmini_context_t config_ctx); |
| 78 | +static void configure_section_drivers(dmfsi_context_t ctx, dmini_context_t config_ctx, const char* config_path); |
76 | 79 | static int unconfigure_drivers(dmfsi_context_t ctx); |
77 | 80 | static bool is_file(const char* path); |
78 | 81 | static bool is_driver( const char* name); |
@@ -852,18 +855,20 @@ static int configure_drivers(dmfsi_context_t ctx, const char* driver_name, const |
852 | 855 | } |
853 | 856 |
|
854 | 857 | driver_node_t* driver_node = configure_driver(module_name, config_ctx); |
855 | | - dmini_destroy(config_ctx); |
856 | | - if (driver_node == NULL) |
| 858 | + if (driver_node != NULL) |
857 | 859 | { |
858 | | - DMOD_LOG_ERROR("Failed to configure driver: %s\n", module_name); |
859 | | - continue; |
| 860 | + if(!dmlist_push_back(ctx->drivers, driver_node)) |
| 861 | + { |
| 862 | + DMOD_LOG_ERROR("Failed to add driver to list: %s\n", module_name); |
| 863 | + Dmod_Free(driver_node); |
| 864 | + } |
860 | 865 | } |
861 | | - if(!dmlist_push_back(ctx->drivers, driver_node)) |
| 866 | + else |
862 | 867 | { |
863 | | - DMOD_LOG_ERROR("Failed to add driver to list: %s\n", module_name); |
864 | | - Dmod_Free(driver_node); |
865 | | - continue; |
| 868 | + DMOD_LOG_ERROR("Failed to configure driver: %s\n", module_name); |
866 | 869 | } |
| 870 | + configure_section_drivers(ctx, config_ctx, full_path); |
| 871 | + dmini_destroy(config_ctx); |
867 | 872 | } |
868 | 873 | else |
869 | 874 | { |
@@ -944,6 +949,86 @@ static driver_node_t* configure_driver(const char* driver_name, dmini_context_t |
944 | 949 | return driver_node; |
945 | 950 | } |
946 | 951 |
|
| 952 | +/** |
| 953 | + * @brief Configure drivers for non-main sections that contain a driver_name key |
| 954 | + * |
| 955 | + * Scans the config file line by line for INI section headers. For each section |
| 956 | + * other than "main" that contains a driver_name key, a new driver is configured |
| 957 | + * with the INI context restricted to that section via dmini_set_active_section, |
| 958 | + * so the driver only sees the keys belonging to its own section. |
| 959 | + */ |
| 960 | +static void configure_section_drivers(dmfsi_context_t ctx, dmini_context_t config_ctx, const char* config_path) |
| 961 | +{ |
| 962 | + void* file = Dmod_FileOpen(config_path, "r"); |
| 963 | + if (file == NULL) |
| 964 | + { |
| 965 | + DMOD_LOG_ERROR("Failed to open config file for section scan: %s\n", config_path); |
| 966 | + return; |
| 967 | + } |
| 968 | + |
| 969 | + char line[INI_LINE_BUFFER_SIZE]; |
| 970 | + while (Dmod_FileReadLine(line, sizeof(line), file) != NULL) |
| 971 | + { |
| 972 | + // Skip lines that don't start with '[' (ignore leading whitespace) |
| 973 | + char* p = line; |
| 974 | + while (*p == ' ' || *p == '\t') p++; |
| 975 | + if (*p != '[') continue; |
| 976 | + |
| 977 | + // Find closing bracket |
| 978 | + char* end = strchr(p, ']'); |
| 979 | + if (end == NULL || end <= p) continue; |
| 980 | + |
| 981 | + // Extract section name |
| 982 | + size_t name_len = (size_t)(end - p - 1); |
| 983 | + if (name_len == 0 || name_len >= DMOD_MAX_MODULE_NAME_LENGTH) continue; |
| 984 | + |
| 985 | + char section_name[DMOD_MAX_MODULE_NAME_LENGTH]; |
| 986 | + strncpy(section_name, p + 1, name_len); |
| 987 | + section_name[name_len] = '\0'; |
| 988 | + |
| 989 | + // Trim trailing whitespace from section name |
| 990 | + size_t slen = strlen(section_name); |
| 991 | + while (slen > 0 && (section_name[slen - 1] == ' ' || section_name[slen - 1] == '\t')) |
| 992 | + { |
| 993 | + slen--; |
| 994 | + } |
| 995 | + section_name[slen] = '\0'; |
| 996 | + |
| 997 | + // Skip empty section names and the "main" section (handled by existing logic) |
| 998 | + if (slen == 0 || strcmp(section_name, INI_MAIN_SECTION) == 0) continue; |
| 999 | + |
| 1000 | + // Check if this section has a driver_name key |
| 1001 | + if (!dmini_has_key(config_ctx, section_name, "driver_name")) continue; |
| 1002 | + |
| 1003 | + const char* drv_name = dmini_get_string(config_ctx, section_name, "driver_name", NULL); |
| 1004 | + if (drv_name == NULL) continue; |
| 1005 | + |
| 1006 | + char module_name[DMOD_MAX_MODULE_NAME_LENGTH]; |
| 1007 | + strncpy(module_name, drv_name, sizeof(module_name)); |
| 1008 | + module_name[sizeof(module_name) - 1] = '\0'; |
| 1009 | + |
| 1010 | + // Restrict the INI context to this section and configure the driver. |
| 1011 | + // Token 0 means no owner-token protection (context was created with dmini_create). |
| 1012 | + dmini_set_active_section(config_ctx, section_name, 0); |
| 1013 | + driver_node_t* driver_node = configure_driver(module_name, config_ctx); |
| 1014 | + dmini_clear_active_section(config_ctx, 0); |
| 1015 | + |
| 1016 | + if (driver_node == NULL) |
| 1017 | + { |
| 1018 | + DMOD_LOG_ERROR("Failed to configure driver for section [%s]: %s\n", section_name, module_name); |
| 1019 | + continue; |
| 1020 | + } |
| 1021 | + |
| 1022 | + if (!dmlist_push_back(ctx->drivers, driver_node)) |
| 1023 | + { |
| 1024 | + DMOD_LOG_ERROR("Failed to add driver to list: %s\n", module_name); |
| 1025 | + Dmod_Free(driver_node); |
| 1026 | + } |
| 1027 | + } |
| 1028 | + |
| 1029 | + Dmod_FileClose(file); |
| 1030 | +} |
| 1031 | + |
947 | 1032 | /** |
948 | 1033 | * @brief Unconfigure and unload all drivers |
949 | 1034 | */ |
|
0 commit comments