static int module_create(MODULE_HOST * module_host, BROKER_HANDLE broker, GATEWAY_MODULE_LOADER_INFO * gw_loader_info, const char * remote_module_args) { int result; if (remote_module_args == NULL) { /*Codes_SRS_NATIVEMODULEHOST_17_026: [ If any step above fails, then NativeModuleHost_Create shall free all resources allocated and return NULL. ]*/ LogError("An error occurred getting module args for module"); result = __LINE__; } else { /*Codes_SRS_NATIVEMODULEHOST_17_019: [ NativeModuleHost_Create shall load the module library with the pasred entrypoint. ]*/ module_host->module_library_handle = gw_loader_info->loader->api->Load( gw_loader_info->loader, gw_loader_info->entrypoint); if (module_host->module_library_handle == NULL) { /*Codes_SRS_NATIVEMODULEHOST_17_026: [ If any step above fails, then NativeModuleHost_Create shall free all resources allocated and return NULL. ]*/ result = __LINE__; } else { MODULE_LOADER_API* loader_api = gw_loader_info->loader->api; /*Codes_SRS_NATIVEMODULEHOST_17_020: [ NativeModuleHost_Create shall get the MODULE_API pointer from the loader. ]*/ const MODULE_API* module_apis = loader_api->GetApi(gw_loader_info->loader, module_host->module_library_handle); if (module_apis == NULL) { /*Codes_SRS_NATIVEMODULEHOST_17_026: [ If any step above fails, then NativeModuleHost_Create shall free all resources allocated and return NULL. ]*/ loader_api->Unload(gw_loader_info->loader, module_host->module_library_handle); result = __LINE__; } else { /*Codes_SRS_NATIVEMODULEHOST_17_021: [ NativeModuleHost_Create shall call the module's _ParseConfigurationFromJson on the "module.args" object. ]*/ const void* module_configuration = MODULE_PARSE_CONFIGURATION_FROM_JSON(module_apis)(remote_module_args); /*Codes_SRS_NATIVEMODULEHOST_17_022: [ NativeModuleHost_Create shall build the module confguration from the parsed entrypoint and parsed module arguments. ]*/ const void* transformed_module_configuration = loader_api->BuildModuleConfiguration( gw_loader_info->loader, gw_loader_info->entrypoint, module_configuration ); /*Codes_SRS_NATIVEMODULEHOST_17_023: [ NativeModuleHost_Create shall call the module's _Create on the built module configuration. ]*/ module_host->module = MODULE_CREATE(module_apis)(broker, transformed_module_configuration); if (module_host->module == NULL) { /*Codes_SRS_NATIVEMODULEHOST_17_026: [ If any step above fails, then NativeModuleHost_Create shall free all resources allocated and return NULL. ]*/ loader_api->Unload(gw_loader_info->loader, module_host->module_library_handle); result = __LINE__; } else { /*Codes_SRS_NATIVEMODULEHOST_17_025: [ NativeModuleHost_Create shall return a non-null pointer to a MODULE_HANDLE on success. ]*/ module_host->module_loader = gw_loader_info->loader; module_host->module_host_broker = broker; result = 0; } /*Codes_SRS_NATIVEMODULEHOST_17_024: [ NativeModuleHost_Create shall free all resources used during module loading. ]*/ MODULE_FREE_CONFIGURATION(module_apis)((void*)module_configuration); loader_api->FreeModuleConfiguration(gw_loader_info->loader, transformed_module_configuration); } } } return result; }
static MODULE_LIBRARY_HANDLE NodeModuleLoader_Load(const MODULE_LOADER* loader, const void* entrypoint) { NODE_MODULE_HANDLE_DATA* result; // loader cannot be null if (loader == NULL) { //Codes_SRS_NODE_MODULE_LOADER_13_001 : [NodeModuleLoader_Load shall return NULL if loader is NULL.] result = NULL; LogError("invalid inputs - loader = %p", loader); } else { if (loader->type != NODEJS) { //Codes_SRS_NODE_MODULE_LOADER_13_002 : [NodeModuleLoader_Load shall return NULL if loader->type is not NODEJS.] result = NULL; LogError("loader->type is not NODEJS"); } else { result = (NODE_MODULE_HANDLE_DATA*)malloc(sizeof(NODE_MODULE_HANDLE_DATA)); if (result == NULL) { //Codes_SRS_NODE_MODULE_LOADER_13_003 : [NodeModuleLoader_Load shall return NULL if an underlying platform call fails.] LogError("malloc returned NULL"); } else { result->binding_module = NodeModuleLoader_LoadBindingModule(loader); if (result->binding_module == NULL) { LogError("NodeModuleLoader_LoadBindingModule returned NULL"); //Codes_SRS_NODE_MODULE_LOADER_13_003 : [NodeModuleLoader_Load shall return NULL if an underlying platform call fails.] free(result); result = NULL; } else { //Codes_SRS_NODE_MODULE_LOADER_13_033: [ NodeModuleLoader_Load shall call DynamicLibrary_FindSymbol on the binding module handle with the symbol name Module_GetApi to acquire the function that returns the module's API table. ] pfModule_GetApi pfnGetAPI = (pfModule_GetApi)DynamicLibrary_FindSymbol(result->binding_module, MODULE_GETAPI_NAME); if (pfnGetAPI == NULL) { DynamicLibrary_UnloadLibrary(result->binding_module); free(result); //Codes_SRS_NODE_MODULE_LOADER_13_003 : [NodeModuleLoader_Load shall return NULL if an underlying platform call fails.] result = NULL; LogError("DynamicLibrary_FindSymbol() returned NULL"); } else { //Codes_SRS_NODE_MODULE_LOADER_13_005 : [NodeModuleLoader_Load shall return a non - NULL pointer of type MODULE_LIBRARY_HANDLE when successful.] result->api = pfnGetAPI(Module_ApiGatewayVersion); //Codes_SRS_NODE_MODULE_LOADER_13_034: [ NodeModuleLoader_Load shall return NULL if the MODULE_API pointer returned by the binding module is NULL. ] //Codes_SRS_NODE_MODULE_LOADER_13_035: [ NodeModuleLoader_Load shall return NULL if MODULE_API::version is greater than Module_ApiGatewayVersion. ] //Codes_SRS_NODE_MODULE_LOADER_13_036: [ NodeModuleLoader_Load shall return NULL if the Module_Create function in MODULE_API is NULL. ] //Codes_SRS_NODE_MODULE_LOADER_13_037: [ NodeModuleLoader_Load shall return NULL if the Module_Receive function in MODULE_API is NULL. ] //Codes_SRS_NODE_MODULE_LOADER_13_038: [ NodeModuleLoader_Load shall return NULL if the Module_Destroy function in MODULE_API is NULL. ] /* if any of the required functions is NULL then we have a misbehaving module */ if (result->api == NULL || result->api->version > Module_ApiGatewayVersion || MODULE_CREATE(result->api) == NULL || MODULE_DESTROY(result->api) == NULL || MODULE_RECEIVE(result->api) == NULL) { LogError( "pfnGetapi() returned an invalid MODULE_API instance. " "result->api = %p, " "result->api->version = %d, " "MODULE_CREATE(result->api) = %p, " "MODULE_DESTROY(result->api) = %p, " "MODULE_RECEIVE(result->api) = %p, ", result->api, result->api != NULL ? result->api->version : 0x0, result->api != NULL ? MODULE_CREATE(result->api) : NULL, result->api != NULL ? MODULE_DESTROY(result->api) : NULL, result->api != NULL ? MODULE_RECEIVE(result->api) : NULL ); DynamicLibrary_UnloadLibrary(result->binding_module); free(result); //Codes_SRS_NODE_MODULE_LOADER_13_003 : [NodeModuleLoader_Load shall return NULL if an underlying platform call fails.] result = NULL; } } } } } } return result; }