doubango/tinySAK/src/tsk_plugin.c
c732d49e
 #if HAVE_CRT
 #define _CRTDBG_MAP_ALLOC 
 #include <stdlib.h> 
 #include <crtdbg.h>
 #endif //HAVE_CRT
 /*
74ca6d11
 * Copyright (C) 2020, University of the Basque Country (UPV/EHU)
c732d49e
 * Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
 *
 * The original file was part of Open Source Doubango Framework
 * Copyright (C) 2010-2011 Mamadou Diop.
 * Copyright (C) 2012 Doubango Telecom <http://doubango.org>
 *
 * This file is part of Open Source Doubango Framework.
 *
 * DOUBANGO is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * DOUBANGO is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with DOUBANGO.
 *
 */
 #include "tsk_plugin.h"
 #include "tsk_string.h"
 #include "tsk_memory.h"
 #include "tsk_debug.h"
 
 typedef int (*symbol_get_def_count)(void);
 typedef tsk_plugin_def_type_t (*symbol_get_def_type_at)(int index);
 typedef tsk_plugin_def_media_type_t (*symbol_get_def_media_type_at)(int index);
 typedef tsk_plugin_def_ptr_const_t (*symbol_get_def_at)(int index);
 
 #define TSK_PLUGIN_FUNC_NAME_DEF_COUNT				"__plugin_get_def_count"
 #define TSK_PLUGIN_FUNC_NAME_DEF_TYPE_AT			"__plugin_get_def_type_at"
 #define TSK_PLUGIN_FUNC_NAME_DEF_MEDIA_TYPE_AT		"__plugin_get_def_media_type_at"
 #define TSK_PLUGIN_FUNC_NAME_DEF_AT					"__plugin_get_def_at"
 
 #if TSK_UNDER_WINDOWS
 #	include <windows.h>
 #else
 #	include <dlfcn.h>
 #endif
 
 #if !TSK_UNDER_WINDOWS_CE
 #include <sys/stat.h> /* stat() */
 #endif
 
 #if (TSK_UNDER_WINDOWS_RT || TSK_UNDER_WINDOWS_CE)
 static const wchar_t* szFormat = L"%hs";
 #endif
 
 static int _tsk_plugin_handle_destroy(tsk_plugin_handle_t** self);
 static tsk_plugin_symbol_t* _tsk_plugin_handle_get_symbol(tsk_plugin_handle_t* handle, const char* symbol_name);
 
 typedef struct tsk_plugin_s
 {
 	TSK_DECLARE_OBJECT;
 
 	tsk_plugin_handle_t* handle;
 	int def_count;
 	char* path;
 }
 tsk_plugin_t;
 
 static tsk_object_t* tsk_plugin_ctor(tsk_object_t * self, va_list * app)
 {
 	tsk_plugin_t *plugin = (tsk_plugin_t*)self;
 	if(plugin){
 		
 	}
 	return self;
 }
 static tsk_object_t* tsk_plugin_dtor(tsk_object_t * self)
 { 
 	tsk_plugin_t *plugin = (tsk_plugin_t*)self;
 	if(plugin){
 		TSK_FREE(plugin->path);
 		_tsk_plugin_handle_destroy(&plugin->handle);
 	}
 
 	return self;
 }
 static const tsk_object_def_t tsk_plugin_def_s = 
 {
 	sizeof(tsk_plugin_t),
 	tsk_plugin_ctor, 
 	tsk_plugin_dtor,
 	tsk_null, 
 };
 
 tsk_plugin_t* tsk_plugin_create(const char* path)
 {
 	tsk_plugin_t* plugin;
 	symbol_get_def_count funcptr_get_def_count;
 	tsk_plugin_handle_t* handle;
 
 #if TSK_UNDER_WINDOWS
 #	if TSK_UNDER_WINDOWS_RT
 	#if HAVE_CRT //Debug memory
 	wchar_t* szPath = (wchar_t*)calloc(tsk_strlen(path) + 1, sizeof(wchar_t));
 		
 	#else
 	wchar_t* szPath = (wchar_t*)tsk_calloc(tsk_strlen(path) + 1, sizeof(wchar_t));
 		
 	#endif //HAVE_CRT
 	swprintf(szPath, tsk_strlen(path) * sizeof(wchar_t), szFormat, path);
 	handle = LoadPackagedLibrary(szPath, 0x00000000);
 	TSK_FREE(szPath);
 #	else /* Windows desktop/CE */
 #if TSK_UNDER_WINDOWS_CE
 	#if HAVE_CRT //Debug memory
 	wchar_t* szPath = (wchar_t*)calloc(tsk_strlen(path) + 1, sizeof(wchar_t));
 		
 	#else
 	wchar_t* szPath = (wchar_t*)tsk_calloc(tsk_strlen(path) + 1, sizeof(wchar_t));
 		
 	#endif //HAVE_CRT
 	swprintf_s(szPath, tsk_strlen(path) * sizeof(wchar_t), szFormat, path);
 	handle = LoadLibrary(szPath);
 	TSK_FREE(szPath);
 #else
 	UINT currErrMode = SetErrorMode(SEM_FAILCRITICALERRORS); // save current ErrorMode. GetErrorMode() not supported on XP.
 	SetErrorMode(currErrMode | SEM_FAILCRITICALERRORS);
 	handle = LoadLibraryA(path);
 	SetErrorMode(currErrMode); // restore ErrorMode
 #endif /* !TSK_UNDER_WINDOWS_CE */
 #	endif /*end-of-else-TSK_UNDER_WINDOWS_RT*/
 #else
 	handle = dlopen(path, RTLD_NOW);
 #endif
 
 	if(!handle){
 		TSK_DEBUG_ERROR("Failed to load library with path=%s", path);
 		return tsk_null;
 	}
 
 	if(!(funcptr_get_def_count = (symbol_get_def_count)_tsk_plugin_handle_get_symbol(handle, TSK_PLUGIN_FUNC_NAME_DEF_COUNT))){
 		TSK_DEBUG_ERROR("Cannot find function with name=%s", TSK_PLUGIN_FUNC_NAME_DEF_COUNT);
 		_tsk_plugin_handle_destroy(&handle);
 		return tsk_null;
 	}
 
 	if(!(plugin = (tsk_plugin_t*)tsk_object_new(&tsk_plugin_def_s))){
 		TSK_DEBUG_ERROR("Failed to create plugin object");
 		_tsk_plugin_handle_destroy(&handle);
 		return tsk_null;
 	}
 
 	plugin->handle = handle;
 	plugin->def_count = funcptr_get_def_count();
 	plugin->path = tsk_strdup(path);
 
 	TSK_DEBUG_INFO("Plugin with path=[%s] created with [%d] defs", plugin->path, plugin->def_count);
 
 	return plugin;
 }
 
 tsk_plugin_def_ptr_const_t tsk_plugin_get_def_2(struct tsk_plugin_s* self, tsk_plugin_def_type_t type, tsk_plugin_def_media_type_t media_type, tsk_size_t index)
 {
 	tsk_plugin_def_ptr_const_t def_ptr_const;
 	symbol_get_def_type_at funcptr_get_def_type_at;
 	symbol_get_def_media_type_at funcptr_get_def_media_type_at;
 	symbol_get_def_at funcptr_get_def_at;
 	int i;
 	tsk_size_t _index = 0;
 
 	if(!self){
 		TSK_DEBUG_ERROR("Invalid parameter");
 		return tsk_null;
 	}
 
 	if(!(funcptr_get_def_type_at = (symbol_get_def_type_at)tsk_plugin_get_symbol(self, TSK_PLUGIN_FUNC_NAME_DEF_TYPE_AT))){
 		TSK_DEBUG_ERROR("[%s] function not implemented in plugin with path=[%s]", TSK_PLUGIN_FUNC_NAME_DEF_TYPE_AT, self->path);
 		return tsk_null;
 	}
 	if(!(funcptr_get_def_media_type_at = (symbol_get_def_media_type_at)tsk_plugin_get_symbol(self, TSK_PLUGIN_FUNC_NAME_DEF_MEDIA_TYPE_AT))){
 		TSK_DEBUG_ERROR("[%s] function not implemented in plugin with path=[%s]", TSK_PLUGIN_FUNC_NAME_DEF_MEDIA_TYPE_AT, self->path);
 		return tsk_null;
 	}
 	if(!(funcptr_get_def_at = (symbol_get_def_at)tsk_plugin_get_symbol(self, TSK_PLUGIN_FUNC_NAME_DEF_AT))){
 		TSK_DEBUG_ERROR("[%s] function not implemented in plugin with path=[%s]", TSK_PLUGIN_FUNC_NAME_DEF_AT, self->path);
 		return tsk_null;
 	}
 
 	for(i = 0; i < self->def_count; ++i){
 		if((funcptr_get_def_type_at(i) & type) && (funcptr_get_def_media_type_at(i) & media_type)){
 			if((def_ptr_const = funcptr_get_def_at(i))){
 				if(_index++ == index){
 					return def_ptr_const;
 				}
 			}
 		}
 	}
 	return tsk_null;
 }
 
 tsk_plugin_def_ptr_const_t tsk_plugin_get_def(tsk_plugin_t* self, tsk_plugin_def_type_t type, tsk_plugin_def_media_type_t media_type)
 {
 	return tsk_plugin_get_def_2(self, type, media_type, 0);
 }
 
 tsk_plugin_symbol_t* tsk_plugin_get_symbol(tsk_plugin_t* self, const char* symbol_name)
 {
 	if(!self || !self->handle || !symbol_name){
 		TSK_DEBUG_ERROR("Invalid parameter");
 		return tsk_null;
 	}
 	return _tsk_plugin_handle_get_symbol(self->handle, symbol_name);
 }
 
 tsk_bool_t tsk_plugin_file_exist(const char* path)
 {
 	if (path) {
 #if TSK_UNDER_WINDOWS_CE
 		#if HAVE_CRT //Debug memory
 		wchar_t* szPath = (wchar_t*)calloc(tsk_strlen(path) + 1, sizeof(wchar_t));
 		
 	#else
 		wchar_t* szPath = (wchar_t*)tsk_calloc(tsk_strlen(path) + 1, sizeof(wchar_t));
 		
 	#endif //HAVE_CRT
 		DWORD dwAttrib;
 		swprintf_s(szPath, tsk_strlen(path) * sizeof(wchar_t), szFormat, path);
 		dwAttrib = GetFileAttributes(szPath);
 		TSK_FREE(szPath);
 		return ((dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) == 0);
 #else
 		struct stat _stat;
 		return (stat(path, &_stat) == 0 && _stat.st_size > 0);
 #endif /* TSK_UNDER_WINDOWS_CE */
 	}
 	return tsk_false;
 }
 
 static tsk_plugin_symbol_t* _tsk_plugin_handle_get_symbol(tsk_plugin_handle_t* handle, const char* symbol_name)
 {
 	if(!handle || !symbol_name){
 		TSK_DEBUG_ERROR("Invalid parameter");
 		return tsk_null;
 	}
 #if TSK_UNDER_WINDOWS
 #	if TSK_UNDER_WINDOWS_CE
 		return (tsk_plugin_symbol_t*)GetProcAddressA((HMODULE)handle, symbol_name);
 #	else
 		return (tsk_plugin_symbol_t*)GetProcAddress((HMODULE)handle, symbol_name);
 #	endif
 #else
 	return (tsk_plugin_symbol_t*)dlsym(handle, symbol_name);
 #endif
 }
 
 static int _tsk_plugin_handle_destroy(tsk_plugin_handle_t** handle)
 {
 	if(handle && *handle){
 #if TSK_UNDER_WINDOWS
 		FreeLibrary((HMODULE)*handle);
 #else
 		dlclose(*handle);
 #endif
 		*handle = tsk_null;
 	}
 	return 0;
 }