Explorar o código

removed the old obsolete Plugin system (commit 1/2)

- Removed @ Autoconf/make and CMake, VC Projects will be cleaned in a additional commit.



git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16203 54d463be-8e91-2dee-dedb-b68131a5f0ec
blacksirius %!s(int64=13) %!d(string=hai) anos
pai
achega
b1881eafee

+ 0 - 1
CMakeLists.txt

@@ -481,7 +481,6 @@ set( RUNTIME_DIRECTORIES
 	"doc"
 	"log"
 	"npc"
-	"plugins"
 	"readme"
 	"sql-files"
 	"tools"

+ 1 - 18
Makefile.in

@@ -18,13 +18,6 @@ else
 	MAP_SQL_DEPENDS=needs_mysql
 endif
 
-WITH_PLUGINS=@WITH_PLUGINS@
-ifeq ($(WITH_PLUGINS),yes)
-	ALL_DEPENDS+=plugins
-	PLUGIN_DEPENDS=common_sql
-else
-	PLUGIN_DEPENDS=no_plugins
-endif
 
 #####################################################################
 .PHONY: sql  \
@@ -33,7 +26,7 @@ endif
 	login_sql \
 	char_sql \
 	map_sql \
-	tools plugins addons \
+	tools \
 	import \
 	clean help
 
@@ -62,9 +55,6 @@ map_sql: $(MAP_SQL_DEPENDS)
 tools:
 	@$(MAKE) -C src/tool
 
-plugins addons: $(PLUGIN_DEPENDS)
-	@$(MAKE) -C src/plugins
-	
 import:
 # 1) create conf/import folder
 # 2) add missing files
@@ -81,7 +71,6 @@ clean:
 	@$(MAKE) -C src/login $@
 	@$(MAKE) -C src/char $@
 	@$(MAKE) -C src/map $@
-	@$(MAKE) -C src/plugins $@
 	@$(MAKE) -C src/tool $@
 
 help:
@@ -94,8 +83,6 @@ help:
 	@echo "'char_sql'    - builds char server (SQL version)"
 	@echo "'map_sql'     - builds map server (SQL version)"
 	@echo "'tools'       - builds all the tools in src/tools"
-	@echo "'plugins'     - builds all the plugins in src/plugins"
-	@echo "'addons'"
 	@echo "'import'      - builds conf/import folder from the template conf/import-tmpl"
 	@echo "'all'         - builds all the above targets"
 	@echo "'sql'         - builds sql servers (targets 'common_sql' 'login_sql' 'char_sql'"
@@ -109,10 +96,6 @@ needs_mysql:
 	@echo "MySQL not found or disabled by the configure script"
 	@exit 1
 
-no_plugins:
-	@echo "Plugins disabled by the configure script"
-	@exit 1
-
 #####################################################################
 # TODO
 

+ 0 - 29
conf/plugin_athena.conf

@@ -1,29 +0,0 @@
-// Athena Plugins Configuration file
-
-// Should we auto search for plugin files and load them?
-// If set to 'yes' you will not need to set 'plugin:' commands
-// in this conf file to load them
-auto_search: no
-
-//------Plugins List -----------
-
-// Just a sample plugin
-//plugin: sample
-
-// GUI core plugin
-//plugin: gui
-
-// Crash and Uptime reporting for CygWin/Linux
-//plugin: sig
-
-// Crash reporting for Windows
-//plugin: exchndl
-
-// Alternative, improved crash reporting for Windows
-//plugin: dbghelpplug
-
-// Process id logging
-//plugin: pid
-
-// Console parser
-//plugin: console

+ 2 - 74
configure

@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 16198 .
+# From configure.in Revision: 16200 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.67.
 #
@@ -604,7 +604,6 @@ MYSQL_CFLAGS
 MYSQL_VERSION
 HAVE_MYSQL
 MYSQL_CONFIG_HOME
-WITH_PLUGINS
 AR
 SET_MAKE
 EGREP
@@ -2125,7 +2124,7 @@ ac_config_files="$ac_config_files 3rdparty/mt19937ar/Makefile 3rdparty/libconfig
 
 ac_config_files="$ac_config_files src/char/Makefile src/login/Makefile"
 
-ac_config_files="$ac_config_files src/map/Makefile src/plugins/Makefile src/tool/Makefile"
+ac_config_files="$ac_config_files src/map/Makefile src/tool/Makefile"
 
 
 ac_ext=c
@@ -4834,76 +4833,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 CFLAGS="$OLD_CFLAGS"
 
 
-#
-# -shared needs position independent code; some platforms emit it
-# always, others need -fPIC
-#
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -fPIC for shared objects" >&5
-$as_echo_n "checking whether $CC needs -fPIC for shared objects... " >&6; }
-OLD_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -shared"
-WITH_PLUGINS="yes"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-		int foo(void)
-		{
-			return 0;
-		}
-
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-		CFLAGS="$OLD_CFLAGS"
-
-else
-
-		if test "$compiler_supports_pic" = "yes" ; then
-			# Verify if -shared really fails due to lack of -fPIC or something else
-			CFLAGS="$CFLAGS -fPIC"
-			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-					int foo(void)
-					{
-						return 0;
-					}
-
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
-					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-					CFLAGS="$OLD_CFLAGS -fPIC"
-
-else
-
-					{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no, but fails for another reason" >&5
-$as_echo "no, but fails for another reason" >&6; }
-					as_fn_error $? "compiler is unable to compile shared objects for an unhandled reason, please report this with attached config.log... stopping" "$LINENO" 5
-
-
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-		else
-			# Disable compilation of plugins (optional), so 'make all' does not fail
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, but unsupported" >&5
-$as_echo "yes, but unsupported" >&6; }
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: compiler is unable to generate position independent code, disabled plugins (optional)" >&5
-$as_echo "$as_me: compiler is unable to generate position independent code, disabled plugins (optional)" >&6;}
-			WITH_PLUGINS="no"
-		fi
-
-
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-
-
-
 #
 # -O2 implies -fstrict-aliasing, but the code is not safe for that
 #
@@ -6374,7 +6303,6 @@ do
     "src/char/Makefile") CONFIG_FILES="$CONFIG_FILES src/char/Makefile" ;;
     "src/login/Makefile") CONFIG_FILES="$CONFIG_FILES src/login/Makefile" ;;
     "src/map/Makefile") CONFIG_FILES="$CONFIG_FILES src/map/Makefile" ;;
-    "src/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/Makefile" ;;
     "src/tool/Makefile") CONFIG_FILES="$CONFIG_FILES src/tool/Makefile" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;

+ 1 - 51
configure.in

@@ -8,7 +8,7 @@ AC_CONFIG_SRCDIR([src/common/cbasetypes.h])
 AC_CONFIG_FILES([Makefile src/common/Makefile])
 AC_CONFIG_FILES([3rdparty/mt19937ar/Makefile 3rdparty/libconfig/Makefile])
 AC_CONFIG_FILES([src/char/Makefile src/login/Makefile])
-AC_CONFIG_FILES([src/map/Makefile src/plugins/Makefile src/tool/Makefile])
+AC_CONFIG_FILES([src/map/Makefile src/tool/Makefile])
 
 AC_GNU_SOURCE
 
@@ -444,56 +444,6 @@ AC_COMPILE_IFELSE(
 CFLAGS="$OLD_CFLAGS"
 
 
-#
-# -shared needs position independent code; some platforms emit it
-# always, others need -fPIC
-#
-AC_MSG_CHECKING([whether $CC needs -fPIC for shared objects])
-OLD_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -shared"
-WITH_PLUGINS="yes"
-AC_LINK_IFELSE(
-	[
-		int foo(void)
-		{
-			return 0;
-		}
-	],
-	[
-		AC_MSG_RESULT([no])
-		CFLAGS="$OLD_CFLAGS"
-	],
-	[
-		if test "$compiler_supports_pic" = "yes" ; then
-			# Verify if -shared really fails due to lack of -fPIC or something else
-			CFLAGS="$CFLAGS -fPIC"
-			AC_LINK_IFELSE(
-				[
-					int foo(void)
-					{
-						return 0;
-					}
-				],
-				[
-					AC_MSG_RESULT([yes])
-					CFLAGS="$OLD_CFLAGS -fPIC"
-				],
-				[
-					AC_MSG_RESULT([no, but fails for another reason])
-					AC_MSG_ERROR([compiler is unable to compile shared objects for an unhandled reason, please report this with attached config.log... stopping])
-				]
-			)
-		else
-			# Disable compilation of plugins (optional), so 'make all' does not fail
-			AC_MSG_RESULT([yes, but unsupported])
-			AC_MSG_NOTICE([compiler is unable to generate position independent code, disabled plugins (optional)])
-			WITH_PLUGINS="no"
-		fi
-	]
-)
-AC_SUBST([WITH_PLUGINS])
-
-
 #
 # -O2 implies -fstrict-aliasing, but the code is not safe for that
 #

BIN=BIN
plugins/dbghelpplug.dll


BIN=BIN
plugins/exchndl.dll


+ 0 - 1
src/CMakeLists.txt

@@ -17,4 +17,3 @@ add_subdirectory( login )
 add_subdirectory( char )
 add_subdirectory( map )
 add_subdirectory( tool )
-add_subdirectory( plugins )

+ 0 - 3
src/common/CMakeLists.txt

@@ -31,7 +31,6 @@ set( COMMON_ALL_HEADERS
 	"${CMAKE_CURRENT_BINARY_DIR}/svnversion.h"
 	"${COMMON_SOURCE_DIR}/cbasetypes.h"
 	"${COMMON_SOURCE_DIR}/mmo.h"
-	"${COMMON_SOURCE_DIR}/plugin.h"
 	)
 
 set( COMMON_MINI_HEADERS
@@ -71,7 +70,6 @@ set( COMMON_BASE_HEADERS
 	"${COMMON_SOURCE_DIR}/mapindex.h"
 	"${COMMON_SOURCE_DIR}/md5calc.h"
 	"${COMMON_SOURCE_DIR}/nullpo.h"
-	"${COMMON_SOURCE_DIR}/plugins.h"
 	"${COMMON_SOURCE_DIR}/random.h"
 	"${COMMON_SOURCE_DIR}/showmsg.h"
 	"${COMMON_SOURCE_DIR}/socket.h"
@@ -92,7 +90,6 @@ set( COMMON_BASE_SOURCES
 	"${COMMON_SOURCE_DIR}/mapindex.c"
 	"${COMMON_SOURCE_DIR}/md5calc.c"
 	"${COMMON_SOURCE_DIR}/nullpo.c"
-	"${COMMON_SOURCE_DIR}/plugins.c"
 	"${COMMON_SOURCE_DIR}/random.c"
 	"${COMMON_SOURCE_DIR}/showmsg.c"
 	"${COMMON_SOURCE_DIR}/socket.c"

+ 1 - 1
src/common/Makefile.in

@@ -1,5 +1,5 @@
 
-COMMON_OBJ = obj_all/core.o obj_all/socket.o obj_all/timer.o obj_all/db.o obj_all/plugins.o obj_all/lock.o \
+COMMON_OBJ = obj_all/core.o obj_all/socket.o obj_all/timer.o obj_all/db.o obj_all/lock.o \
 	obj_all/nullpo.o obj_all/malloc.o obj_all/showmsg.o obj_all/strlib.o obj_all/utils.o \
 	obj_all/grfio.o obj_all/mapindex.o obj_all/ers.o obj_all/md5calc.o \
 	obj_all/minicore.o obj_all/minisocket.o obj_all/minimalloc.o obj_all/random.o obj_all/des.o \

+ 0 - 5
src/common/core.c

@@ -9,7 +9,6 @@
 #include "../common/db.h"
 #include "../common/socket.h"
 #include "../common/timer.h"
-#include "../common/plugins.h"
 #endif
 
 #include <stdio.h>
@@ -288,10 +287,8 @@ int main (int argc, char **argv)
 
 	timer_init();
 	socket_init();
-	plugins_init();
 
 	do_init(argc,argv);
-	plugin_event_trigger(EVENT_ATHENA_INIT);
 
 	{// Main runtime cycle
 		int next;
@@ -301,11 +298,9 @@ int main (int argc, char **argv)
 		}
 	}
 
-	plugin_event_trigger(EVENT_ATHENA_FINAL);
 	do_final();
 
 	timer_final();
-	plugins_final();
 	socket_final();
 	db_final();
 #endif

+ 0 - 86
src/common/plugin.h

@@ -1,86 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#ifndef	_PLUGIN_H_
-#define _PLUGIN_H_
-
-#include "../common/cbasetypes.h"
-
-////// Plugin functions ///////////////
-
-// Plugin version <major version>.<minor version>
-// * <major version> is increased and <minor version> reset when at least one 
-//   export of the previous version becomes incompatible
-// * <minor version> is increased if the previous version remains compatible
-// 
-// Compatible plugins have:
-// - equal major version
-// - lower or equal minor version
-#define PLUGIN_VERSION "1.03"
-
-typedef struct _Plugin_Info {
-	char* name;
-	char type;
-	char* version;
-	char* req_version;
-	char* description;
-} Plugin_Info;
-
-typedef struct _Plugin_Event_Table {
-	char* func_name;
-	char* event_name;
-} Plugin_Event_Table;
-
-// Format of the test function
-typedef int Plugin_Test_Func(void);
-#define EVENT_PLUGIN_INIT		"Plugin_Init"  // Initialize the plugin
-#define EVENT_PLUGIN_FINAL		"Plugin_Final" // Finalize the plugin
-#define EVENT_ATHENA_INIT		"Athena_Init"  // Server started
-#define EVENT_ATHENA_FINAL		"Athena_Final" // Server ended
-
-// Format of event functions
-typedef void Plugin_Event_Func(void);
-#define EVENT_PLUGIN_TEST		"Plugin_Test" // Test the plugin for compatibility
-
-////// Plugin Export functions /////////////
-
-#define PLUGIN_ALL			0
-#define PLUGIN_LOGIN		1
-#define PLUGIN_CHAR			2
-#define PLUGIN_MAP			8
-#define PLUGIN_CORE			16
-
-#define IMPORT_SYMBOL(s,n)	SET_FUNCPOINTER((s), plugin_call_table[n])
-
-#define SYMBOL_SERVER_TYPE				0
-#define SYMBOL_SERVER_NAME				1
-#define SYMBOL_ARG_C					2
-#define SYMBOL_ARG_V					3
-#define SYMBOL_RUNFLAG					4
-#define SYMBOL_GETTICK					5
-#define SYMBOL_GET_SVN_REVISION			6
-#define SYMBOL_ADD_TIMER				7
-#define SYMBOL_ADD_TIMER_INTERVAL		8
-#define SYMBOL_ADD_TIMER_FUNC_LIST		9
-#define SYMBOL_DELETE_TIMER				10
-#define SYMBOL_GET_UPTIME				11
-#define SYMBOL_ADDR						12
-#define SYMBOL_FD_MAX					13
-#define SYMBOL_SESSION					14
-#define SYMBOL_DELETE_SESSION			15
-#define SYMBOL_WFIFOSET					16
-#define SYMBOL_RFIFOSKIP				17
-#define SYMBOL_FUNC_PARSE_TABLE			18
-// 1.03
-#define SYMBOL_PARSE_CONSOLE			19
-
-////// Global Plugin variables /////////////
-
-#define PLUGIN_INFO			struct _Plugin_Info plugin_info
-#define PLUGIN_EVENTS_TABLE	struct _Plugin_Event_Table plugin_event_table[]
-
-#ifndef	_PLUGINS_H_
-void** plugin_call_table;
-#endif
-
-#endif /* _PLUGIN_H_ */

+ 0 - 415
src/common/plugins.c

@@ -1,415 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#include "../common/mmo.h"
-#include "../common/core.h"
-#include "../common/timer.h"
-#include "../common/utils.h" // findfile()
-#include "../common/socket.h"
-#include "../common/malloc.h"
-#include "../common/showmsg.h"
-#include "plugins.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifndef WIN32
-#include <unistd.h>
-#endif
-
-//////////////////////////////////////////////
-
-typedef struct _Plugin_Event {
-	struct _Plugin_Event* next;
-	Plugin_Event_Func* func;
-} Plugin_Event;
-
-typedef struct _Plugin_Event_List {
-	struct _Plugin_Event_List* next;
-	char* name;
-	struct _Plugin_Event* events;
-} Plugin_Event_List;
-
-static int auto_search = 0;
-static int load_priority = 0;
-Plugin_Event_List* event_head = NULL;
-Plugin* plugin_head = NULL;
-
-static Plugin_Info default_info = { "Unknown", PLUGIN_ALL, "0", PLUGIN_VERSION, "Unknown" };
-
-void** plugin_call_table;
-static size_t call_table_size	= 0;
-static size_t max_call_table	= 0;
-
-////// Plugin Events Functions //////////////////
-
-int register_plugin_func(char* name)
-{
-	Plugin_Event_List* evl;
-	if( name ){
-		//ShowDebug("register_plugin_func(%s)\n", name);
-		CREATE(evl, Plugin_Event_List, 1);
-		evl->next = event_head;
-		evl->name = aStrdup(name);
-		evl->events = NULL;
-		event_head = evl;
-	}
-	return 0;
-}
-
-static Plugin_Event_List* search_plugin_func(char* name)
-{
-	Plugin_Event_List* evl = event_head;
-	while( evl ){
-		if( strcmpi(evl->name,name) == 0 )
-			return evl;
-		evl = evl->next;
-	}
-	return NULL;
-}
-
-int register_plugin_event(Plugin_Event_Func* func, char* name)
-{
-	Plugin_Event_List* evl = search_plugin_func(name);
-	//ShowDebug("register_plugin_event(0x%x, %s)\n", func, name);
-	if( !evl )
-	{// event does not exist, register
-		register_plugin_func(name);
-		// get the new event list
-		evl = search_plugin_func(name);
-	}
-	if( evl ){
-		Plugin_Event* ev;
-
-		CREATE(ev, Plugin_Event, 1);
-		ev->func = func;
-		ev->next = NULL;
-
-		// insert event at the end of the linked list
-		if( evl->events == NULL )
-			evl->events = ev;
-		else {
-			Plugin_Event* last_ev = evl->events;
-			while( last_ev ){
-				if( last_ev->next == NULL ){
-					last_ev->next = ev;
-					break;
-				}
-				last_ev = last_ev->next;
-			}
-		}
-	}
-	return 0;
-}
-
-int plugin_event_trigger(char* name)
-{
-	int c = 0;
-	Plugin_Event_List* evl = search_plugin_func(name);
-	//ShowDebug("plugin_event_trigger(%s)\n", name);
-	if( evl ){
-		Plugin_Event* ev = evl->events;
-		while( ev ){
-			ev->func();
-			//ShowDebug("plugin_event_trigger: Executing function 0x%x.\n", ev->func);
-			ev = ev->next;
-			++c;
-		}
-	}
-	return c;
-}
-
-////// Plugins Call Table Functions /////////
-
-int export_symbol(void* var, size_t offset)
-{
-	//ShowDebug("export_symbol(0x%x,%d)\n", var,offset);
-
-	// add to the end of the list
-	if( offset < 0 )
-		offset = call_table_size;
-
-	if( offset >= max_call_table )
-	{// realloc if not large enough  
-		max_call_table = 1 + offset;
-		RECREATE(plugin_call_table, void*, max_call_table);
-
-		// clear the new alloced block
-		memset(plugin_call_table + call_table_size, 0, (max_call_table-call_table_size)*sizeof(void*));
-	}
-
-	// the new table size is delimited by the new element at the end
-	if( offset >= call_table_size )
-		call_table_size = offset+1;
-
-	// put the pointer at the selected place
-	plugin_call_table[offset] = var;
-	return 0;
-}
-
-////// Plugins Core /////////////////////////
-
-static int plugin_iscompatible(char* version)
-{
-	int req_major = 0;
-	int req_minor = 0;
-	int major = 0;
-	int minor = 0;
-
-	if( version == NULL )
-		return 0;
-	sscanf(version, "%d.%d", &req_major, &req_minor);
-	sscanf(PLUGIN_VERSION, "%d.%d", &major, &minor);
-	return ( req_major == major && req_minor <= minor );
-}
-
-Plugin* plugin_open(const char* filename)
-{
-	Plugin* plugin;
-	Plugin_Info* info;
-	Plugin_Event_Table* events;
-	void** procs;
-	int init_flag = 1;
-
-	//ShowDebug("plugin_open(%s)\n", filename);
-	
-	// Check if the plugin has been loaded before
-	plugin = plugin_head;
-	while (plugin) {
-		// returns handle to the already loaded plugin
-		if( plugin->state && strcmpi(plugin->filename, filename) == 0 ){
-			ShowWarning("plugin_open: not loaded (duplicate) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
-			return plugin;
-		}
-		plugin = plugin->next;
-	}
-
-	CREATE(plugin, Plugin, 1);
-	plugin->state = -1;	// not loaded
-
-	plugin->dll = DLL_OPEN(filename);
-	if( !plugin->dll ){
-		ShowWarning("plugin_open: not loaded (invalid file) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
-		plugin_unload(plugin);
-		return NULL;
-	}
-
-	// Retrieve plugin information
-	plugin->state = 0;	// initialising
-	info = (Plugin_Info*)DLL_SYM(plugin->dll, "plugin_info");
-	// For high priority plugins (those that are explicitly loaded from the conf file)
-	// we'll ignore them even (could be a 3rd party dll file)
-	if( !info )
-	{// foreign plugin
-		//ShowDebug("plugin_open: plugin_info not found\n");
-		if( load_priority == 0 )
-		{// not requested
-			//ShowDebug("plugin_open: not loaded (not requested) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
-			plugin_unload(plugin);
-			return NULL;
-		}
-	} else if( !plugin_iscompatible(info->req_version) )
-	{// incompatible version
-		ShowWarning("plugin_open: not loaded (incompatible version '%s' -> '%s') : '"CL_WHITE"%s"CL_RESET"'\n", info->req_version, PLUGIN_VERSION, filename);
-		plugin_unload(plugin);
-		return NULL;
-	} else if( (info->type != PLUGIN_ALL && info->type != PLUGIN_CORE && info->type != SERVER_TYPE) ||
-		(info->type == PLUGIN_CORE && SERVER_TYPE != PLUGIN_LOGIN && SERVER_TYPE != PLUGIN_CHAR && SERVER_TYPE != PLUGIN_MAP) )
-	{// not for this server
-		//ShowDebug("plugin_open: not loaded (incompatible) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
-		plugin_unload(plugin);
-		return NULL;
-	}
-
-	plugin->info = ( info != NULL ? info : &default_info );
-	plugin->filename = aStrdup(filename);
-
-	// Initialise plugin call table (For exporting procedures)
-	procs = (void**)DLL_SYM(plugin->dll, "plugin_call_table");
-	if( procs )
-		*procs = plugin_call_table;
-	//else ShowDebug("plugin_open: plugin_call_table not found\n");
-
-	// Register plugin events
-	events = (Plugin_Event_Table*)DLL_SYM(plugin->dll, "plugin_event_table");
-	if( events ){
-		int i = 0;
-		//ShowDebug("plugin_open: parsing plugin_event_table\n");
-		while( events[i].func_name ){
-			if( strcmpi(events[i].event_name, EVENT_PLUGIN_TEST) == 0 ){
-				Plugin_Test_Func* test_func;
-				test_func = (Plugin_Test_Func*)DLL_SYM(plugin->dll, events[i].func_name);
-				//ShowDebug("plugin_open: invoking "EVENT_PLUGIN_TEST" with %s()\n", events[i].func_name);
-				if( test_func && test_func() == 0 ){
-					// plugin has failed test, disabling
-					//ShowDebug("plugin_open: disabled (failed test) : %s\n", filename);
-					init_flag = 0;
-				}
-			} else {
-				Plugin_Event_Func* func;
-				func = (Plugin_Event_Func*)DLL_SYM(plugin->dll, events[i].func_name);
-				if (func)
-					register_plugin_event(func, events[i].event_name);
-				else
-					ShowError("Failed to locate function '%s' in '%s'.\n", events[i].func_name, filename);
-			}
-			i++;
-		}
-	}
-	//else ShowDebug("plugin_open: plugin_event_table not found\n");
-
-	plugin->next = plugin_head;
-	plugin_head = plugin;
-
-	plugin->state = init_flag;	// fully loaded
-	ShowStatus("Done loading plugin '"CL_WHITE"%s"CL_RESET"'\n", (info) ? plugin->info->name : filename);
-
-	return plugin;
-}
-
-void plugin_load(const char* filename)
-{
-	plugin_open(filename);
-}
-
-void plugin_unload(Plugin* plugin)
-{
-	if( plugin == NULL )
-		return;
-	if( plugin->filename )
-		aFree(plugin->filename);
-	if( plugin->dll )
-		DLL_CLOSE(plugin->dll);
-	aFree(plugin);
-}
-
-#ifdef WIN32
-char *DLL_ERROR(void)
-{
-	static char dllbuf[80];
-	DWORD dw = GetLastError();
-	FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, 0, dllbuf, 80, NULL);
-	return dllbuf;
-}
-#endif
-
-////// Initialize/Finalize ////////////////////
-
-static int plugins_config_read(const char *cfgName)
-{
-	char line[1024], w1[1024], w2[1024];
-	FILE *fp;
-
-	fp = fopen(cfgName, "r");
-	if( fp == NULL ){
-		ShowError("File not found: %s\n", cfgName);
-		return 1;
-	}
-	while( fgets(line, sizeof(line), fp) )
-	{
-		if( line[0] == '/' && line[1] == '/' )
-			continue;
-		if( sscanf(line,"%[^:]: %[^\r\n]",w1,w2) != 2 )
-			continue;
-
-		if( strcmpi(w1,"auto_search") == 0 ){
-			if( strcmpi(w2,"yes") == 0 )
-				auto_search = 1;
-			else if( strcmpi(w2,"no") == 0 )
-				auto_search = 0;
-			else
-				auto_search = atoi(w2);
-		} else if( strcmpi(w1,"plugin") == 0 ){
-			char filename[128];
-			sprintf(filename, "plugins/%s%s", w2, DLL_EXT);
-			plugin_load(filename);
-		} else if( strcmpi(w1,"import") == 0 )
-			plugins_config_read(w2);
-		else
-			ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
-	}
-	fclose(fp);
-	return 0;
-}
-
-void plugins_init(void)
-{
-	// Sugested functionality:
-	// add atcommands/script commands (Borf)
-	char* PLUGIN_CONF_FILENAME = "conf/plugin_athena.conf";
-	//ShowDebug("plugins_init()\n");
-	register_plugin_func(EVENT_PLUGIN_INIT);
-	register_plugin_func(EVENT_PLUGIN_FINAL);
-	register_plugin_func(EVENT_ATHENA_INIT);
-	register_plugin_func(EVENT_ATHENA_FINAL);
-
-	// networking
-	EXPORT_SYMBOL(RFIFOSKIP,  SYMBOL_RFIFOSKIP);
-	EXPORT_SYMBOL(WFIFOSET,   SYMBOL_WFIFOSET);
-	EXPORT_SYMBOL(do_close,   SYMBOL_DELETE_SESSION);
-	EXPORT_SYMBOL(session,    SYMBOL_SESSION);
-	EXPORT_SYMBOL(&fd_max,    SYMBOL_FD_MAX);
-	EXPORT_SYMBOL(addr_,      SYMBOL_ADDR);
-	// timers
-	EXPORT_SYMBOL(get_uptime,              SYMBOL_GET_UPTIME);
-	EXPORT_SYMBOL(delete_timer,            SYMBOL_DELETE_TIMER);
-	EXPORT_SYMBOL(add_timer_func_list,     SYMBOL_ADD_TIMER_FUNC_LIST);
-	EXPORT_SYMBOL(add_timer_interval,      SYMBOL_ADD_TIMER_INTERVAL);
-	EXPORT_SYMBOL(add_timer,               SYMBOL_ADD_TIMER);
-	EXPORT_SYMBOL((void*)get_svn_revision, SYMBOL_GET_SVN_REVISION);
-	EXPORT_SYMBOL(gettick,                 SYMBOL_GETTICK);
-	// core
-	EXPORT_SYMBOL(parse_console, SYMBOL_PARSE_CONSOLE);
-	EXPORT_SYMBOL(&runflag,      SYMBOL_RUNFLAG);
-	EXPORT_SYMBOL(arg_v,         SYMBOL_ARG_V);
-	EXPORT_SYMBOL(&arg_c,        SYMBOL_ARG_C);
-	EXPORT_SYMBOL(SERVER_NAME,   SYMBOL_SERVER_NAME);
-	EXPORT_SYMBOL(&SERVER_TYPE,  SYMBOL_SERVER_TYPE);
-
-	load_priority = 1;
-	plugins_config_read(PLUGIN_CONF_FILENAME);
-	load_priority = 0;
-
-	if( auto_search )
-		findfile("plugins", DLL_EXT, plugin_load);
-
-	plugin_event_trigger(EVENT_PLUGIN_INIT);
-
-	return;
-}
-
-void plugins_final(void)
-{
-	Plugin* plugin = plugin_head;
-	Plugin* next_plugin;
-	Plugin_Event_List* evl = event_head;
-	Plugin_Event_List* next_evl;
-	Plugin_Event* ev;
-	Plugin_Event* next_ev;
-
-	//ShowDebug("plugins_final()\n");
-	plugin_event_trigger(EVENT_PLUGIN_FINAL);
-
-	while( plugin ){
-		next_plugin = plugin->next;
-		plugin_unload(plugin);
-		plugin = next_plugin;
-	}
-
-	while( evl ){
-		ev = evl->events;
-		while( ev ){
-			next_ev = ev->next;
-			aFree(ev);
-			ev = next_ev;
-		}
-		next_evl = evl->next;
-		aFree(evl->name);
-		aFree(evl);
-		evl = next_evl;
-	}
-
-	aFree(plugin_call_table);
-
-	return;
-}

+ 0 - 69
src/common/plugins.h

@@ -1,69 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#ifndef	_PLUGINS_H_
-#define _PLUGINS_H_
-
-#include "../common/cbasetypes.h"
-#include "../common/plugin.h"
-
-////// Dynamic Link Library functions ///////////////
-
-#ifdef WIN32
-
-	#define WIN32_LEAN_AND_MEAN
-	#include <windows.h>
-	#define DLL_OPEN(x)		LoadLibraryA(x)
-	#define DLL_SYM(x,y)	GetProcAddress(x,y)
-	#define DLL_CLOSE(x)	FreeLibrary(x)
-	char *DLL_ERROR(void);
-
-	#define DLL_EXT			".dll"
-	#define DLL				HINSTANCE
-
-#else
-
-	#include <dlfcn.h>
-	#define DLL_OPEN(x)		dlopen(x,RTLD_NOW)
-	#define DLL_SYM(x,y)	dlsym(x,y)
-	#define DLL_CLOSE(x)	dlclose(x)
-	#define DLL_ERROR		dlerror
-
-	#ifdef CYGWIN
-		#define DLL_EXT		".dll"
-	#else
-		#define DLL_EXT		".so"
-	#endif
-	#define DLL				void *
-
-	#include <string.h> // size_t
-
-#endif
-
-////// Plugin Definitions ///////////////////
-
-typedef struct _Plugin {
-	DLL dll;
-	char state;
-	char* filename;
-	struct _Plugin_Info* info;
-	struct _Plugin* next;
-} Plugin;
-
-/////////////////////////////////////////////
-
-int register_plugin_func(char* name);
-int register_plugin_event(Plugin_Event_Func* func, char* name);
-int plugin_event_trigger(char* name);
-
-int export_symbol(void* var, size_t offset);
-#define EXPORT_SYMBOL(s,o) export_symbol((void*)(s),(o));
-#define EXPORT_SYMBOL2(s) EXPORT_SYMBOL((s), -1);
-
-Plugin* plugin_open(const char* filename);
-void plugin_load(const char* filename);
-void plugin_unload(Plugin* plugin);
-void plugins_init(void);
-void plugins_final(void);
-
-#endif /* _PLUGINS_H_ */

+ 0 - 174
src/plugins/CMakeLists.txt

@@ -1,174 +0,0 @@
-
-#
-# setup
-#
-get_property( CAN_BUILD_SHARED_LIBS  GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS )
-if( NOT CAN_BUILD_SHARED_LIBS )
-	return()
-endif()
-
-#
-# console
-#
-option( BUILD_PLUGIN_console "build console plugin" OFF )
-if( BUILD_PLUGIN_console )
-message( STATUS "Creating target console" )
-set( CONSOLE_SOURCES
-	"${CMAKE_CURRENT_SOURCE_DIR}/console.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/console.def"
-	)
-set( LIBRARIES ${GLOBAL_LIBRARIES} )
-set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
-set( SOURCE_FILES ${CONSOLE_SOURCES} )
-source_group( console FILES ${CONSOLE_SOURCES} )
-include_directories( ${INCLUDE_DIRS} )
-add_library( console SHARED ${SOURCE_FILES} )
-target_link_libraries( console ${LIBRARIES} )
-set_target_properties( console PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
-set_target_properties( console PROPERTIES PREFIX "" )
-if( INSTALL_COMPONENT_RUNTIME )
-	cpack_add_component( Runtime_console DESCRIPTION "console plugin" DISPLAY_NAME "console" GROUP Runtime )
-	install( TARGETS console
-		DESTINATION "plugins"
-		COMPONENT Runtime_console )
-endif( INSTALL_COMPONENT_RUNTIME )
-set( TARGET_LIST ${TARGET_LIST} console  CACHE INTERNAL "" )
-message( STATUS "Creating target console - done" )
-endif( BUILD_PLUGIN_console )
-
-
-#
-# dbghelpplug
-#
-if( WIN32 )
-	find_path( HAVE_DBGHELP_H dbghelp.h )
-	mark_as_advanced( HAVE_DBGHELP_H )
-	if( HAVE_DBGHELP_H )
-		option( BUILD_PLUGIN_dbghelpplug "build dbghelpplug plugin" OFF )
-	endif()
-endif()
-if( NOT DEFINED BUILD_PLUGIN_dbghelpplug )
-	message( STATUS "Disabled dbghelpplug plugin target (requires WIN32 and HAVE_DBGHELP_H)" )
-endif()
-if( BUILD_PLUGIN_dbghelpplug )
-message( STATUS "Creating target dbghelpplug" )
-set( DBGHELPPLUG_SOURCES
-	"${CMAKE_CURRENT_SOURCE_DIR}/dbghelpplug.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/dbghelpplug.rc"
-	)
-set( LIBRARIES ${GLOBAL_LIBRARIES} )
-set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
-set( SOURCE_FILES ${DBGHELPPLUG_SOURCES} )
-source_group( dbghelpplug FILES ${DBGHELPPLUG_SOURCES} )
-include_directories( ${INCLUDE_DIRS} )
-add_library( dbghelpplug SHARED ${SOURCE_FILES} )
-target_link_libraries( dbghelpplug ${LIBRARIES} )
-set_target_properties( dbghelpplug PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
-set_target_properties( dbghelpplug PROPERTIES PREFIX "" )
-if( INSTALL_COMPONENT_RUNTIME )
-	cpack_add_component( Runtime_dbghelpplug DESCRIPTION "dbghelpplug plugin" DISPLAY_NAME "dbghelpplug" GROUP Runtime )
-	install( TARGETS dbghelpplug
-		DESTINATION "plugins"
-		COMPONENT Runtime_dbghelpplug )
-endif( INSTALL_COMPONENT_RUNTIME )
-set( TARGET_LIST ${TARGET_LIST} dbghelpplug  CACHE INTERNAL "" )
-message( STATUS "Creating target dbghelpplug - done" )
-endif( BUILD_PLUGIN_dbghelpplug )
-
-
-#
-# pid
-#
-if( WIN32 OR HAVE_GETPID )
-	option( BUILD_PLUGIN_pid "build pid plugin" OFF )
-else()
-	message( STATUS "Disabled pid plugin target (requires WIN32 or HAVE_GETPID)" )
-endif()
-if( BUILD_PLUGIN_pid )
-message( STATUS "Creating target pid" )
-set( PID_SOURCES
-	"${CMAKE_CURRENT_SOURCE_DIR}/pid.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/pid.def"
-	)
-set( LIBRARIES ${GLOBAL_LIBRARIES} )
-set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
-set( SOURCE_FILES ${PID_SOURCES} )
-source_group( pid FILES ${PID_SOURCES} )
-include_directories( ${INCLUDE_DIRS} )
-add_library( pid SHARED ${SOURCE_FILES} )
-target_link_libraries( pid ${LIBRARIES} )
-set_target_properties( pid PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
-set_target_properties( pid PROPERTIES PREFIX "" )
-if( INSTALL_COMPONENT_RUNTIME )
-	cpack_add_component( Runtime_pid DESCRIPTION "pid plugin" DISPLAY_NAME "pid" GROUP Runtime )
-	install( TARGETS pid
-		DESTINATION "plugins"
-		COMPONENT Runtime_pid )
-endif( INSTALL_COMPONENT_RUNTIME )
-set( TARGET_LIST ${TARGET_LIST} pid  CACHE INTERNAL "" )
-message( STATUS "Creating target pid - done" )
-endif( BUILD_PLUGIN_pid )
-
-
-#
-# sample
-#
-option( BUILD_PLUGIN_sample "build sample plugin" OFF )
-if( BUILD_PLUGIN_sample )
-message( STATUS "Creating target sample" )
-set( SAMPLE_SOURCES
-	"${CMAKE_CURRENT_SOURCE_DIR}/sample.c"
-	"${CMAKE_CURRENT_SOURCE_DIR}/sample.def"
-	)
-set( LIBRARIES ${GLOBAL_LIBRARIES} )
-set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
-set( SOURCE_FILES ${SAMPLE_SOURCES} )
-source_group( sample FILES ${SAMPLE_SOURCES} )
-include_directories( ${INCLUDE_DIRS} )
-add_library( sample SHARED ${SOURCE_FILES} )
-target_link_libraries( sample ${LIBRARIES} )
-set_target_properties( sample PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
-set_target_properties( sample PROPERTIES PREFIX "" )
-if( INSTALL_COMPONENT_RUNTIME )
-	cpack_add_component( Runtime_sample DESCRIPTION "sample plugin" DISPLAY_NAME "sample" GROUP Runtime )
-	install( TARGETS sample
-		DESTINATION "plugins"
-		COMPONENT Runtime_sample )
-endif( INSTALL_COMPONENT_RUNTIME )
-set( TARGET_LIST ${TARGET_LIST} sample  CACHE INTERNAL "" )
-message( STATUS "Creating target sample - done" )
-endif( BUILD_PLUGIN_sample )
-
-
-#
-# sig
-#
-option( BUILD_PLUGIN_sig "build sig plugin" OFF )
-if( BUILD_PLUGIN_sig )
-message( STATUS "Creating target sig" )
-set( SIG_SOURCES
-	"${CMAKE_CURRENT_SOURCE_DIR}/sig.c"
-	)
-set( LIBRARIES ${GLOBAL_LIBRARIES} )
-set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
-set( DEFINITIONS "${GLOBAL_DEFINITIONS} -DNO_MEMMGR" )
-set( SOURCE_FILES ${SIG_SOURCES} )
-source_group( sig FILES ${SIG_SOURCES} )
-include_directories( ${INCLUDE_DIRS} )
-add_library( sig SHARED ${SOURCE_FILES} )
-target_link_libraries( sig ${LIBRARIES} )
-set_target_properties( sig PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" )
-set_target_properties( sig PROPERTIES PREFIX "" )
-if( INSTALL_COMPONENT_RUNTIME )
-	cpack_add_component( Runtime_sig DESCRIPTION "sig plugin" DISPLAY_NAME "sig" GROUP Runtime )
-	install( TARGETS sig
-		DESTINATION "plugins"
-		COMPONENT Runtime_sig )
-endif( INSTALL_COMPONENT_RUNTIME )
-set( TARGET_LIST ${TARGET_LIST} sig  CACHE INTERNAL "" )
-message( STATUS "Creating target sig - done" )
-endif( BUILD_PLUGIN_sig )

+ 0 - 54
src/plugins/Makefile.in

@@ -1,54 +0,0 @@
-
-COMMON_OBJ = ../common/obj_all/showmsg.o ../common/obj_all/utils.o ../common/obj_all/strlib.o \
-	../common/obj_all/minimalloc.o
-COMMON_H = ../common/plugin.h ../common/cbasetypes.h \
-	../common/showmsg.h ../common/utils.h ../common/strlib.h \
-	../common/malloc.h
-
-PLUGINS = sample sig pid console
-
-@SET_MAKE@
-
-#####################################################################
-.PHONY : all $(PLUGINS) clean help
-
-all: $(PLUGINS)
-
-sample: sample@DLLEXT@
-
-sig: sig@DLLEXT@
-
-pid: pid@DLLEXT@
-
-console: console@DLLEXT@
-
-clean:
-	@echo "	CLEAN	plugins"
-	@rm -rf *.o
-
-help:
-	@echo "possible targets are $(PLUGINS:%='%') 'all' 'clean' 'help'"
-	@echo "'sample'   - sample plugin"
-	@echo "'sig'      - signal handler plugin"
-	@echo "'pid'      - process id plugin"
-	@echo "'console'  - console plugin"
-	@echo "'all'      - builds all above targets"
-	@echo "'clean'    - cleans builds and objects"
-	@echo "'help'     - outputs this message"
-
-#####################################################################
-
-%@DLLEXT@: %.c
-	@echo "	CC	$<"
-	@@CC@ @CFLAGS@ @CPPFLAGS@ @LDFLAGS@ -shared -o ../../plugins/$@ $<
-
-sig@DLLEXT@: sig.c $(COMMON_OBJ)
-	@echo "	CC	$<"
-	@@CC@ @CFLAGS@ @CPPFLAGS@ @LDFLAGS@ -shared -o ../../plugins/$@ $< $(COMMON_OBJ)
-
-# missing common object files
-../common/obj_all/%.o: ../common/%.c $(COMMON_H)
-	@$(MAKE) -C ../common txt
-
-../common/obj_all/mini%.o: ../common/%.c $(COMMON_H)
-	@$(MAKE) -C ../common txt

+ 0 - 496
src/plugins/console.c

@@ -1,496 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#include "../common/plugin.h"
-
-#ifdef WIN32
-	#define WIN32_LEAN_AND_MEAN
-	#include <windows.h>
-#else
-	#define __USE_XOPEN
-	#include <sys/types.h>
-	#include <unistd.h>
-	#include <poll.h>
-	#include <string.h>
-#endif
-#include <stdio.h> // stdin, fgets
-
-#define INPUT_BUFSIZE 4096
-#define INPUT_INVALID 0
-#define INPUT_READY   1
-#define INPUT_WAITING 2
-#define INPUT_READING 3
-#define INPUT_CLOSED  4
-
-//////////////////////////////
-#ifdef WIN32
-//////////////////////////////
-
-// In windows the worker is a thread so it can access the same variables.
-#define WORKER_FUNC_DECLARE(name) DWORD WINAPI worker_ ## name(LPVOID lpParameter)
-#define WORKER_FUNC_START(name) DWORD WINAPI worker_ ## name(LPVOID lpParameter) { (void)lpParameter; {
-#define WORKER_FUNC_END(name) } ExitThread(0); return 0; }
-#define WORKER_EXECUTE(name,errvar) \
-	do{ \
-		DWORD dwThreadId; \
-		buf.worker = CreateThread(NULL, 0, worker_ ## name, NULL, CREATE_SUSPENDED, &dwThreadId); \
-		*(errvar) = ( buf.worker == NULL ); \
-	}while(0)
-
-/// Buffer for asynchronous input
-typedef struct _buffer {
-	char arr[INPUT_BUFSIZE];
-	size_t len;
-	HANDLE worker;
-	HANDLE state_mux; // mutex for the state
-	char state;
-} BUFFER;
-
-//////////////////////////////
-#else
-//////////////////////////////
-
-/// In linux the worker is a process so it needs to comunicate through pipes.
-#define WORKER_FUNC_DECLARE(name) void worker_ ## name(void)
-#define WORKER_FUNC_START(name) void worker_ ## name(void) {
-#define WORKER_FUNC_END(name) _exit(0); }
-#define WORKER_EXECUTE(name,errvar) \
-	do{ \
-		int pid = fork(); \
-		if( pid == 0 ){ \
-			worker_ ## name(); \
-		} \
-		*(errvar) = (pid == -1); \
-	}while(0)
-
-#define PIPE_READ 0
-#define PIPE_WRITE 1
-
-/// Buffer for asynchronous input
-typedef struct _buffer {
-	char arr[INPUT_BUFSIZE];
-	size_t len;
-	int data_pipe[2]; // pipe to receive data
-	int state_pipe[2]; // pipe to send state
-	char state;
-	unsigned close_unused_flag : 1;
-} BUFFER;
-
-//////////////////////////////
-#endif
-//////////////////////////////
-
-
-
-
-
-////// Plugin information ////////
-
-
-
-
-
-PLUGIN_INFO = {
-	"Console", // Name
-	PLUGIN_ALL, // Target servers
-	"0.1", // Version
-	"1.03", // Minimum plugin engine version to run
-	"Console parser" // Short description
-};
-
-////// Plugin event list //////////
-// Format: <plugin function>,<event name>
-// All registered functions to a event gets executed
-// (In descending order) when its called.
-// Multiple functions can be called by multiple events too,
-// So it's up to your creativity ^^
-//
-PLUGIN_EVENTS_TABLE = {
-	{ "console_init",      EVENT_PLUGIN_INIT },
-	{ "console_final",     EVENT_PLUGIN_FINAL },
-	{ "console_autostart", EVENT_ATHENA_INIT },
-	//{ "console_start",     EVENT_CONSOLE_START },//## add these events to the plugins framework
-	//{ "console_stop",      EVENT_CONSOLE_STOP },
-	{ "console_stop",      EVENT_ATHENA_FINAL },
-	{ NULL, NULL }
-};
-
-
-
-
-
-///// Variables /////
-
-
-
-
-
-// Imported functions
-typedef int (*TimerFunc)(int tid, unsigned int tick, int id, intptr_t data);
-int (*add_timer_func_list)(TimerFunc func, char* name);
-int (*add_timer_interval)(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval);
-int (*delete_timer)(int tid, TimerFunc func);
-unsigned int (*gettick)(void);
-int (*parse_console)(const char* buf);
-
-// Locals
-int tid = -1; // timer id
-BUFFER buf; // input buffer
-WORKER_FUNC_DECLARE(getinput); // worker for the input buffer
-
-
-
-
-
-//////// Asynchronous input functions //////////
-
-
-
-
-
-//////////////////////////////
-#ifdef WIN32
-//////////////////////////////
-//
-// --=== Asynchronous console input ===--
-//
-// On windows a thread is used (both threads have access to the same data).
-// The worker threads starts suspended and is resumed when data is required.
-// After getting the data, the worker thread updates the state variable and 
-// suspends itself.
-//
-// A mutex is used to synchronize access to the state variable between the 
-// threads. Access and updates to state are probably already atomic so the 
-// mutex shouldn't be needed, but using it is more correct so it stays.
-//
-// Note: The Worker thread only starts to get input data when further data is 
-//    requested. This is a design choise and brings no real advantage or 
-//    disadvantage I can think of.
-//
-
-/// Returns the state of the input
-char input_getstate()
-{
-	char state;
-
-	WaitForSingleObject(buf.state_mux, INFINITE);
-	state = buf.state;
-	ReleaseMutex(buf.state_mux);
-
-	return state;
-}
-
-/// Sets the state of the input
-void input_setstate(char state)
-{
-	char oldstate;
-
-	// update state
-	WaitForSingleObject(buf.state_mux, INFINITE);
-	oldstate = buf.state;
-	buf.state = state;
-	ReleaseMutex(buf.state_mux);
-
-	if( state == INPUT_READY && oldstate == INPUT_READING )
-	{// data has become available
-		SuspendThread(buf.worker);
-	} else if( state == INPUT_WAITING )
-	{// input is waiting for data
-		ResumeThread(buf.worker);
-	//} else if( state == INPUT_READING )
-	//{// worker is reading data
-	} else if( state == INPUT_CLOSED )
-	{// end the input
-		CloseHandle(buf.state_mux);
-		TerminateThread(buf.worker, 0);
-	}
-}
-
-/// Gets the next state of the input
-#define input_nextstate() input_getstate()
-
-/// Returns if data is available from asynchronous input.
-/// Requests data if none is available.
-int input_hasdata(void)
-{
-	if( input_getstate() == INPUT_READY )
-	{// buffer is ready
-		if( buf.len > 0 )
-			return 1; // data found ;)
-		// request data from the worker
-		input_setstate(INPUT_WAITING);
-	}
-	return 0; // no data
-}
-
-/// Initialize asynchronous input
-int input_init(void)
-{
-	int err = 0;
-
-	memset(&buf, 0, sizeof(buf));
-	buf.state_mux = CreateMutex(NULL, FALSE, NULL);
-	if( buf.state_mux == NULL )
-	{// failed to create state mutex
-		return 1;
-	}
-	buf.len = 0;
-	input_setstate(INPUT_READY);
-	WORKER_EXECUTE(getinput, &err);
-	if( err )
-	{// failed to start worker
-		input_setstate(INPUT_CLOSED);
-	}
-
-	return err;
-}
-
-/// Finalize asynchronous input
-int input_final(void)
-{
-	input_setstate(INPUT_CLOSED);
-	return 0;
-}
-
-//////////////////////////////
-#else
-//////////////////////////////
-//
-// --=== Asynchronous console input ===--
-//
-// On the other systems a process is used and pipes are used to comunicate.
-// The worker process receives status updates through one of the pipes either 
-// requesting data or ending the worker.
-// The other pipe is used by the worker to send the input data and is checked 
-// for data by the main thread in the timer function.
-//
-// Note: The Worker thread only starts to get input data when further data is 
-//    requested. This is a design choise and brings no real advantage or 
-//    disadvantage I can think of.
-//
-
-/// Returns the state of the input
-#define input_getstate() buf.state
-
-/// Sets the state of the input
-void input_setstate(char state) {
-	size_t fileReadCount = 0;
-	if( state == INPUT_READY && input_getstate() == INPUT_READING ) {// send data from the worker to the main process
-		fileReadCount = write(buf.data_pipe[PIPE_WRITE], &buf.len, sizeof(buf.len));
-		fileReadCount = write(buf.data_pipe[PIPE_WRITE], &buf.arr, buf.len);
-	} else if( state == INPUT_WAITING ) {
-		if( buf.close_unused_flag == 0 ) {// close unused pipe sides in the main process
-			close(buf.data_pipe[PIPE_WRITE]);
-			close(buf.state_pipe[PIPE_READ]);
-			buf.close_unused_flag = 1;
-		}
-		// send the next state
-		fileReadCount = write(buf.state_pipe[PIPE_WRITE], &state, sizeof(state));
-	} else if( state == INPUT_READING ) {
-		if( buf.close_unused_flag == 0 ) {// close unused pipe sides in the worker process
-			close(buf.data_pipe[PIPE_READ]);
-			close(buf.state_pipe[PIPE_WRITE]);
-			buf.close_unused_flag = 1;
-		}
-	} else if( state == INPUT_CLOSED ) {// send next state to the worker and close the pipes
-		fileReadCount = write(buf.state_pipe[PIPE_WRITE], &state, sizeof(state));
-		close(buf.data_pipe[PIPE_WRITE]);
-		close(buf.data_pipe[PIPE_READ]);
-		close(buf.state_pipe[PIPE_WRITE]);
-		close(buf.state_pipe[PIPE_READ]);
-	}
-	buf.state = state;
-}
-
-/// Waits for the next state of the input
-char input_nextstate()
-{
-	char state = INPUT_CLOSED;
-	int bytes = 0;
-
-	while( bytes == 0 )
-		bytes = read(buf.state_pipe[PIPE_READ], &state, sizeof(state));
-	if( bytes == -1 )
-	{// error, terminate worker
-		input_setstate(INPUT_CLOSED);
-	}
-	return state;
-}
-
-/// Returns if data is available from asynchronous input.
-/// If data is available, it's put in the local buffer.
-int input_hasdata()
-{
-	struct pollfd fds;
-	int hasData;
-	size_t fileReadCount;
-	
-	
-	if( input_getstate() == INPUT_READY ) {// start getting data
-		input_setstate(INPUT_WAITING);
-		return 0;
-	}
-	// check if data is available
-	fds.fd = buf.data_pipe[PIPE_READ];
-	fds.events = POLLRDNORM;
-	hasData = ( poll(&fds,1,0) > 0 );
-	if( hasData ) {// read the data from the pipe
-		fileReadCount = read(buf.data_pipe[PIPE_READ], &buf.len, sizeof(buf.len));
-		fileReadCount = read(buf.data_pipe[PIPE_READ], buf.arr, buf.len);
-		input_setstate(INPUT_READY);
-	}
-
-	return hasData;
-}
-
-/// Initialize asynchronous input
-int input_init(void)
-{
-	int err = 0;
-
-	memset(&buf, 0, sizeof(buf));
-	if( pipe(buf.data_pipe) )
-	{// error creating data pipe
-		return 1;
-	}
-	if( pipe(buf.state_pipe) )
-	{// error creating state pipe
-		close(buf.data_pipe[PIPE_READ]);
-		close(buf.data_pipe[PIPE_WRITE]);
-		return 1;
-	}
-	buf.len = 0;
-	input_setstate(INPUT_READY);
-	WORKER_EXECUTE(getinput, &err);
-	if( err ){
-		//printf("input_init failed to start worker (%d)\n", err);
-		input_setstate(INPUT_CLOSED);
-	}
-
-	return err;
-}
-
-/// Finalize asynchronous input
-int input_final(void)
-{
-	close(buf.data_pipe[PIPE_READ]);
-	close(buf.data_pipe[PIPE_WRITE]);
-	close(buf.state_pipe[PIPE_READ]);
-	close(buf.state_pipe[PIPE_WRITE]);
-	return 0;
-}
-
-//////////////////////////////
-#endif
-//////////////////////////////
-
-
-
-/// Returns the input data array
-#define input_getdata() buf.arr
-
-/// Returns the input data length
-#define input_getlen() buf.len
-
-/// Clear the input data
-#define input_clear() ( buf.len = 0 )
-
-/// Worker thread/process that gets input
-WORKER_FUNC_START(getinput)
-	while( input_nextstate() != INPUT_CLOSED )
-	{// get input
-		input_setstate(INPUT_READING);
-		buf.arr[0] = '\0';
-		if( fgets(buf.arr, INPUT_BUFSIZE, stdin) != NULL )
-			buf.len = strlen(buf.arr);
-		input_setstate(INPUT_READY);
-	}
-WORKER_FUNC_END(getinput)
-
-
-
-
-
-//////// Plugin console functions //////////
-
-
-
-
-
-/// Timer function that checks if there's assynchronous input data and feeds parse_console()
-/// The input reads one line at a time and line terminators are removed.
-int console_getinputtimer(int tid, unsigned int tick, int id, intptr_t data)
-{
-	char* cmd;
-	size_t len;
-
-	if( input_hasdata() ){
-
-		// get data (removes line terminators)
-		cmd = input_getdata();
-		len = input_getlen();
-		while( len > 0 && (cmd[len-1] == '\r' || cmd[len-1] == '\n') )
-			cmd[--len] = '\0';
-
-		// parse data
-		parse_console(cmd);
-		input_clear();
-	}
-
-	return 0;
-}
-
-/// Start the console
-void console_start(void)
-{
-	if( input_init() ){
-		return;
-	}
-	//##TODO add a 'startupcmd' config options
-	//parse_console("help");
-	add_timer_func_list(console_getinputtimer,"console_getinputtimer");
-	tid = add_timer_interval(gettick(),console_getinputtimer,0,0,250);//##TODO add a 'timerperiod' config option
-}
-
-void console_autostart(void)
-{//##TODO add an 'autostart' config option
-	console_start();
-}
-
-/// Stop the console
-void console_stop(void)
-{
-	if( tid != -1 ){
-		delete_timer(tid, console_getinputtimer);
-		input_final();
-	}
-	return;
-}
-
-/// Test the console for compatibility
-int console_test(void)
-{// always compatible at the moment, maybe test if standard input is available?
-	return 1;
-}
-
-
-/// Initialize the console
-void console_init(void)
-{
-	// import symbols
-	IMPORT_SYMBOL(add_timer_interval, SYMBOL_ADD_TIMER_INTERVAL);
-	IMPORT_SYMBOL(add_timer_func_list, SYMBOL_ADD_TIMER_FUNC_LIST);
-	IMPORT_SYMBOL(delete_timer, SYMBOL_DELETE_TIMER);
-	IMPORT_SYMBOL(gettick, SYMBOL_GETTICK);
-	IMPORT_SYMBOL(parse_console, SYMBOL_PARSE_CONSOLE);
-	//printf("%d -> add_timer_func_list=0x%x\n", SYMBOL_ADD_TIMER_FUNC_LIST, (int)add_timer_func_list);
-	//printf("%d -> add_timer_interval=0x%x\n", SYMBOL_ADD_TIMER_INTERVAL, (int)add_timer_interval);
-	//printf("%d -> delete_timer=0x%x\n", SYMBOL_DELETE_TIMER, (int)delete_timer);
-	//printf("%d -> gettick=0x%x\n", SYMBOL_GETTICK, (int)gettick);
-	//printf("%d -> parse_console=0x%x\n", SYMBOL_PARSE_CONSOLE, (int)parse_console);
-}
-
-/// Finalize the console
-void console_final(void)
-{
-}

+ 0 - 13
src/plugins/console.def

@@ -1,13 +0,0 @@
-EXPORTS
-	; common exports
-	plugin_info         DATA
-	plugin_event_table  DATA
-	plugin_call_table   DATA
-	
-	; console-specific exports
-	console_init
-	console_final
-	console_test
-	console_autostart
-	console_start
-	console_stop

+ 0 - 1896
src/plugins/dbghelpplug.c

@@ -1,1896 +0,0 @@
-/*
- * 2008 January 19
- *
- * The author disclaims copyright to this source code.  In place of
- * a legal notice, here is a blessing:
- *
- *    May you do good and not evil.
- *    May you find forgiveness for yourself and forgive others.
- *    May you share freely, never taking more than you give.
- *
- ********************************************************************
- *
- * DONE:
- * - Command line
- * - Windows version
- * - Exception
- * - Registers
- * - Stacktrace (frame number starting at 0)
- * + Functions:
- *   - address
- *   - name
- *   - offset in the function
- *   - line number and source file
- *   - source code of the line (external source)
- *   - function parameters
- *   - local function variables
- * + Variables/parameters:
- *   - variable name
- *   - variable type (char/wchar, integers, floats, enums, arrays, 
- *     pointers, structs, unions, ...)
- *   - readability of memory
- *   - value of char/wchar
- *   - value of integers
- *   - value of floats
- *   - value of enums (hex number)
- *   - values of arrays
- *   - address of pointers
- *   - value of simple pointers (not pointing to another pointer)
- *   - show (char*) and (wchar*) as nul-terminated strings
- *   - show chars/wchar escaped
- * + Modules:
- *   - base address
- *   - file
- *   - version
- *   - size
- *
- * TODO:
- * + Variables/parameters:
- *   - structure members
- *   - union members
- *   - globals
- * - Portability to MinGW
- *
- * $Id$
- */
-
-#ifdef _WIN32
-
-
-/////////////////////////////////////////////////////////////////////
-// Include files 
-//
-
-#include <assert.h>
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#define _NO_CVCONST_H
-#include <dbghelp.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-
-
-/////////////////////////////////////////////////////////////////////
-// Types from Cvconst.h (DIA SDK) 
-//
-
-#ifdef _NO_CVCONST_H
-
-typedef enum _BasicType
-{ 
-   btNoType   = 0,
-   btVoid     = 1,
-   btChar     = 2,
-   btWChar    = 3,
-   btInt      = 6,
-   btUInt     = 7,
-   btFloat    = 8,
-   btBCD      = 9,
-   btBool     = 10,
-   btLong     = 13,
-   btULong    = 14,
-   btCurrency = 25,
-   btDate     = 26,
-   btVariant  = 27,
-   btComplex  = 28,
-   btBit      = 29,
-   btBSTR     = 30,
-   btHresult  = 31
-} BasicType;
-
-typedef enum _UdtKind
-{
-    UdtStruct,
-    UdtClass,
-    UdtUnion
-} UdtKind;
-/*
-typedef enum _SymTag { 
-   SymTagNull             = 0,
-   SymTagExe              = 1,
-   SymTagCompiland        = 2,
-   SymTagCompilandDetails = 3,
-   SymTagCompilandEnv     = 4,
-   SymTagFunction         = 5,
-   SymTagBlock            = 6,
-   SymTagData             = 7,
-   SymTagAnnotation       = 8,
-   SymTagLabel            = 9,
-   SymTagPublicSymbol     = 10,
-   SymTagUDT              = 11,
-   SymTagEnum             = 12,
-   SymTagFunctionType     = 13,
-   SymTagPointerType      = 14,
-   SymTagArrayType        = 15,
-   SymTagBaseType         = 16,
-   SymTagTypedef          = 17,
-   SymTagBaseClass        = 18,
-   SymTagFriend           = 19,
-   SymTagFunctionArgType  = 20,
-   SymTagFuncDebugStart   = 21,
-   SymTagFuncDebugEnd     = 22,
-   SymTagUsingNamespace   = 23,
-   SymTagVTableShape      = 24,
-   SymTagVTable           = 25,
-   SymTagCustom           = 26,
-   SymTagThunk            = 27,
-   SymTagCustomType       = 28,
-   SymTagManagedType      = 29,
-   SymTagDimension        = 30
-} SymTag;
-*/
-#endif /* _NO_CVCONST_H */
-
-
-/////////////////////////////////////////////////////////////////////
-// dbghelp function prototypes
-//
-
-typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(
-	HANDLE hProcess,
-	DWORD ProcessId,
-	HANDLE hFile,
-	MINIDUMP_TYPE DumpType,
-	CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
-	CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
-	CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam
-);
-typedef BOOL (WINAPI *SYMINITIALIZE)(
-	HANDLE  hProcess,
-	PSTR    UserSearchPath,
-	BOOL    fInvadeProcess
-);
-typedef DWORD (WINAPI *SYMSETOPTIONS)(
-	DWORD   SymOptions
-);
-typedef DWORD (WINAPI *SYMGETOPTIONS)(
-	VOID
-);
-typedef BOOL (WINAPI *SYMCLEANUP)(
-	HANDLE  hProcess
-);
-typedef BOOL (WINAPI *SYMGETTYPEINFO)(
-	HANDLE                      hProcess,
-	DWORD64                     ModBase,
-	ULONG                       TypeId,
-	IMAGEHLP_SYMBOL_TYPE_INFO   GetType,
-	PVOID                       pInfo
-);
-typedef BOOL (WINAPI *SYMGETLINEFROMADDR)(
-	HANDLE          hProcess,
-	DWORD           dwAddr,
-	PDWORD          pdwDisplacement,
-	PIMAGEHLP_LINE  Line
-);
-typedef BOOL (WINAPI *SYMENUMSYMBOLS)(
-	HANDLE                          hProcess,
-	ULONG64                         BaseOfDll,
-	PCSTR                           Mask,
-	PSYM_ENUMERATESYMBOLS_CALLBACK  EnumSymbolsCallback,
-	PVOID                           UserContext
-);
-typedef BOOL (WINAPI *SYMSETCONTEXT)(
-	HANDLE                  hProcess,
-	PIMAGEHLP_STACK_FRAME   StackFrame,
-	PIMAGEHLP_CONTEXT       Context
-);
-typedef BOOL (WINAPI *SYMFROMADDR)(
-	HANDLE          hProcess,
-	DWORD64         Address,
-	PDWORD64        Displacement,
-	PSYMBOL_INFO    Symbol
-);
-typedef BOOL (WINAPI *STACKWALK)(
-	DWORD                           MachineType,
-	HANDLE                          hProcess,
-	HANDLE                          hThread,
-	LPSTACKFRAME                    StackFrame,
-	PVOID                           ContextRecord,
-	PREAD_PROCESS_MEMORY_ROUTINE    ReadMemoryRoutine,
-	PFUNCTION_TABLE_ACCESS_ROUTINE  FunctionTableAccessRoutine,
-	PGET_MODULE_BASE_ROUTINE        GetModuleBaseRoutine,
-	PTRANSLATE_ADDRESS_ROUTINE      TranslateAddress
-);
-typedef PVOID (WINAPI *SYMFUNCTIONTABLEACCESS)(
-	HANDLE  hProcess,
-	DWORD   AddrBase
-);
-typedef DWORD (WINAPI *SYMGETMODULEBASE)(
-	HANDLE  hProcess,
-	DWORD   dwAddr
-);
-
-
-/////////////////////////////////////////////////////////////////////
-// Custom info
-
-/// Internal structure used to pass some data around
-typedef struct _InternalData {
-	// PrintStacktrace
-	FILE* log_file;
-	STACKFRAME* pStackframe;
-	HANDLE hProcess;
-	DWORD nr_of_frame;
-
-	// PrintFunctionDetail
-	BOOL as_arg_list;
-	BOOL log_params;
-	BOOL log_locals;
-	BOOL log_globals;
-	DWORD nr_of_var;
-
-	// PrintDataInfo
-	ULONG64 modBase;
-} InterData;
-
-/// dbghelp dll filename
-#define DBGHELP_DLL "dbghelp.dll"
-
-// Default report filename, used when the module path is unavailable
-#define DBG_DEFAULT_FILENAME "athena"
-
-// Extended information printed in the console
-#define DBG_EXTENDED_INFORMATION \
-		"Please report the crash in the bug tracker:\n" \
-		"http://www.eathena.ws/board/index.php?autocom=bugtracker\n"
-
-
-/////////////////////////////////////////////////////////////////////
-// Global variables
-
-HANDLE dbghelp_dll = INVALID_HANDLE_VALUE;
-MINIDUMPWRITEDUMP MiniDumpWriteDump_ = NULL;
-SYMINITIALIZE SymInitialize_ = NULL;
-SYMSETOPTIONS SymSetOptions_ = NULL;
-SYMGETOPTIONS SymGetOptions_ = NULL;
-SYMCLEANUP SymCleanup_ = NULL;
-SYMGETTYPEINFO SymGetTypeInfo_ = NULL;
-SYMGETLINEFROMADDR SymGetLineFromAddr_ = NULL;
-SYMENUMSYMBOLS SymEnumSymbols_ = NULL;
-SYMSETCONTEXT SymSetContext_ = NULL;
-SYMFROMADDR SymFromAddr_ = NULL;
-STACKWALK StackWalk_ = NULL;
-SYMFUNCTIONTABLEACCESS SymFunctionTableAccess_ = NULL;
-SYMGETMODULEBASE SymGetModuleBase_ = NULL;
-
-
-
-/////////////////////////////////////////////////////////////////////
-// Code
-
-
-/// Writes the minidump to file. The callback function will at the 
-/// same time write the list of modules to the log file.
-///
-/// @param file Filename of the minidump
-/// @param ptrs Exception info
-/// @param module_callback Callback for MiniDumpWriteDump
-/// @param log_file Log file
-static VOID
-Dhp__WriteMinidumpFile(
-	const char*                 file,
-	PEXCEPTION_POINTERS         ptrs,
-	MINIDUMP_CALLBACK_ROUTINE   module_callback,
-	FILE*                       log_file)
-{
-	// open minidump file
-	HANDLE minidump_file = CreateFileA(
-		file,
-		GENERIC_WRITE,
-		0,
-		NULL,
-		CREATE_ALWAYS,
-		FILE_ATTRIBUTE_NORMAL,
-		NULL
-	);
-
-	if( minidump_file != INVALID_HANDLE_VALUE )
-	{
-		MINIDUMP_EXCEPTION_INFORMATION expt_info;
-		MINIDUMP_CALLBACK_INFORMATION dump_cb_info;
-
-		expt_info.ThreadId = GetCurrentThreadId();
-		expt_info.ExceptionPointers = ptrs;
-		expt_info.ClientPointers = FALSE;
-
-		dump_cb_info.CallbackRoutine = module_callback;
-		dump_cb_info.CallbackParam = (void*)log_file;
-
-		if( module_callback != NULL && log_file != NULL )
-			fprintf(log_file, "\n\nLoaded modules:\n");
-
-		MiniDumpWriteDump_(
-			GetCurrentProcess(),
-			GetCurrentProcessId(),
-			minidump_file,
-			MiniDumpNormal,
-			ptrs ? &expt_info : NULL,
-			NULL,
-			&dump_cb_info
-		);
-
-		CloseHandle(minidump_file);
-	}
-}
-
-
-/// Prints module information to the log file.
-/// Used as a callback to MiniDumpWriteDump.
-///
-/// @param data Log file
-/// @param callback_input
-/// @param callback_output
-/// @return
-static BOOL CALLBACK
-Dhp__PrintModuleInfoCallback(
-	void*                           data,
-	CONST PMINIDUMP_CALLBACK_INPUT  callback_input,
-	PMINIDUMP_CALLBACK_OUTPUT       callback_output)
-{
-	if( data != NULL &&
-		callback_input != NULL &&
-		callback_input->CallbackType == ModuleCallback)
-	{
-		FILE* log_file = (FILE*)data;
-		MINIDUMP_MODULE_CALLBACK module = callback_input->Module;
-
-		fprintf(log_file, "0x%p", module.BaseOfImage);
-
-		fprintf(log_file, "  %ws", module.FullPath, log_file);
-
-		fprintf(log_file, "  (%d.%d.%d.%d, %d bytes)\n",
-			HIWORD(module.VersionInfo.dwFileVersionMS),
-			LOWORD(module.VersionInfo.dwFileVersionMS),
-			HIWORD(module.VersionInfo.dwFileVersionLS),
-			LOWORD(module.VersionInfo.dwFileVersionLS),
-			module.SizeOfImage);
-	}
-
-	return TRUE;
-}
-
-
-/// Prints details about the current process, platform and exception 
-/// information to the log file.
-///
-/// @param exception Exception info
-/// @param context Exception context
-/// @param log_file Log file
-static VOID
-Dhp__PrintProcessInfo(
-	EXCEPTION_RECORD*   exception,
-	CONTEXT*            context,
-	FILE*               log_file)
-{
-	OSVERSIONINFOA oi;
-	LPSTR cmd_line;
-
-	fprintf(log_file,
-		"\nProcess info:\n");
-
-	// print the command line
-	cmd_line = GetCommandLineA();
-	if( cmd_line )
-	fprintf(log_file,
-		"Cmd line: %s\n",
-		cmd_line);
-
-	// print information about the OS
-	oi.dwOSVersionInfoSize = sizeof(oi);
-	GetVersionExA(&oi);
-	fprintf(log_file,
-		"Platform: Windows OS version %d.%d build %d %s\n",
-		oi.dwMajorVersion, oi.dwMinorVersion, oi.dwBuildNumber, oi.szCSDVersion);
-
-	// print the exception code
-	if( exception )
-	{
-		fprintf(log_file,
-			"\nException:\n"
-			"0x%x",
-			exception->ExceptionCode);
-		switch( exception->ExceptionCode )
-		{
-#define PRINT(x) case x: fprintf(log_file, " "#x); break
-		PRINT(EXCEPTION_ACCESS_VIOLATION);
-		PRINT(EXCEPTION_DATATYPE_MISALIGNMENT);
-		PRINT(EXCEPTION_BREAKPOINT);
-		PRINT(EXCEPTION_SINGLE_STEP);
-		PRINT(EXCEPTION_ARRAY_BOUNDS_EXCEEDED);
-		PRINT(EXCEPTION_FLT_DENORMAL_OPERAND);
-		PRINT(EXCEPTION_FLT_DIVIDE_BY_ZERO);
-		PRINT(EXCEPTION_FLT_INEXACT_RESULT);
-		PRINT(EXCEPTION_FLT_INVALID_OPERATION);
-		PRINT(EXCEPTION_FLT_OVERFLOW);
-		PRINT(EXCEPTION_FLT_STACK_CHECK);
-		PRINT(EXCEPTION_FLT_UNDERFLOW);
-		PRINT(EXCEPTION_INT_DIVIDE_BY_ZERO);
-		PRINT(EXCEPTION_INT_OVERFLOW);
-		PRINT(EXCEPTION_PRIV_INSTRUCTION);
-		PRINT(EXCEPTION_IN_PAGE_ERROR);
-		PRINT(EXCEPTION_ILLEGAL_INSTRUCTION);
-		PRINT(EXCEPTION_NONCONTINUABLE_EXCEPTION);
-		PRINT(EXCEPTION_STACK_OVERFLOW);
-		PRINT(EXCEPTION_INVALID_DISPOSITION);
-		PRINT(EXCEPTION_GUARD_PAGE);
-		PRINT(EXCEPTION_INVALID_HANDLE);
-#undef PRINT
-		}
-
-		// print where the fault occured
-		fprintf(log_file, " at location 0x%p", exception->ExceptionAddress);
-
-		// if the exception was an access violation, print additional information
-		if( exception->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && exception->NumberParameters >= 2 )
-			fprintf(log_file, " %s location 0x%p", exception->ExceptionInformation[0] ? "writing to" : "reading from", exception->ExceptionInformation[1]);
-
-		fprintf(log_file, "\n");
-	}
-
-	// print the register info
-	if( context )
-	{
-#if defined(_M_IX86)
-		fprintf(log_file,
-			"\nRegisters:\n");
-		if( context->ContextFlags & CONTEXT_INTEGER )
-		{
-			fprintf(log_file,
-				"eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n",
-				context->Eax, context->Ebx, context->Ecx,
-				context->Edx, context->Esi, context->Edi);
-		}
-		if( context->ContextFlags & CONTEXT_CONTROL )
-		{
-			fprintf(log_file,
-				"eip=%08x esp=%08x ebp=%08x iopl=%1x %s %s %s %s %s %s %s %s %s %s\n",
-				context->Eip, context->Esp, context->Ebp, 
-				(context->EFlags >> 12) & 3,	//  IOPL level value
-				context->EFlags & 0x00100000 ? "vip" : "   ",	//  VIP (virtual interrupt pending)
-				context->EFlags & 0x00080000 ? "vif" : "   ",	//  VIF (virtual interrupt flag)
-				context->EFlags & 0x00000800 ? "ov"  : "nv",	//  VIF (virtual interrupt flag)
-				context->EFlags & 0x00000400 ? "dn"  : "up",	//  OF (overflow flag)
-				context->EFlags & 0x00000200 ? "ei"  : "di",	//  IF (interrupt enable flag)
-				context->EFlags & 0x00000080 ? "ng"  : "pl",	//  SF (sign flag)
-				context->EFlags & 0x00000040 ? "zr"  : "nz",	//  ZF (zero flag)
-				context->EFlags & 0x00000010 ? "ac"  : "na",	//  AF (aux carry flag)
-				context->EFlags & 0x00000004 ? "po"  : "pe",	//  PF (parity flag)
-				context->EFlags & 0x00000001 ? "cy"  : "nc");	//  CF (carry flag)
-		}
-		if( context->ContextFlags & CONTEXT_SEGMENTS )
-		{
-			fprintf(log_file,
-				"cs=%04x  ss=%04x  ds=%04x  es=%04x  fs=%04x  gs=%04x",
-				context->SegCs,
-				context->SegSs,
-				context->SegDs,
-				context->SegEs,
-				context->SegFs,
-				context->SegGs,
-				context->EFlags);
-			if( context->ContextFlags & CONTEXT_CONTROL )
-				fprintf(log_file,
-					"             efl=%08x",
-					context->EFlags);
-			fprintf(log_file, "\n");
-		}
-		else if( context->ContextFlags & CONTEXT_CONTROL )
-			fprintf(log_file,
-					"                                                                       efl=%08x\n",
-					context->EFlags);
-#else /* defined(_M_IX86) */
-		//TODO add more processors
-#endif
-	}
-}
-
-
-/// Prints the typename of the symbol.
-///
-/// @param typeIndex Type index of the symbol
-/// @param symtag Symbol tag
-/// @param withParens If brackets are printed around the typename
-/// @param interData Inter data
-static VOID
-Dhp__PrintTypeName(
-	DWORD       typeIndex,
-	DWORD       symtag,
-	BOOL        withParens,
-	InterData*  interData)
-{
-	// inter data
-	FILE* log_file;
-	HANDLE hProcess;
-	ULONG64 modBase;
-	//
-	assert( interData != NULL );
-	log_file = interData->log_file;
-	hProcess = interData->hProcess;
-	modBase  = interData->modBase;
-
-	if( withParens )
-		fprintf(log_file, "(");
-
-	switch( symtag )
-	{
-	case SymTagEnum:
-		{
-			WCHAR* pwszTypeName;
-
-			if( SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_SYMNAME, &pwszTypeName) )
-			{
-				fprintf(log_file, "enum %ls", pwszTypeName);
-				LocalFree(pwszTypeName);
-			}
-			else
-				fprintf(log_file, "enum <symname not found>");
-		}
-		break;
-	case SymTagBaseType:
-		{
-			DWORD basetype;
-			ULONG64 length = 0;
-
-			SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_LENGTH, &length);
-			if( !SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_BASETYPE, &basetype) )
-			{
-				fprintf(log_file, "<basetype not found>");
-				break;
-			}
-			switch( basetype )
-			{
-			case btVoid: fprintf(log_file, "void"); break;
-			case btChar: fprintf(log_file, "char"); break;
-			case btWChar: fprintf(log_file, "wchar"); break;
-			case btULong: fprintf(log_file, "unsigned ");	// next
-			case btLong: fprintf(log_file, "long"); break;
-			case btUInt: fprintf(log_file, "unsigned ");	// next
-			case btInt:
-				if( length == sizeof(char) ) fprintf(log_file, "char");
-				else if( length == sizeof(short) ) fprintf(log_file, "short");
-				else if( length == sizeof(int) ) fprintf(log_file, "int");
-				else if( length == sizeof(long long) ) fprintf(log_file, "long long");
-				else fprintf(log_file, "<int%d>", length*8);
-				break;
-			case btFloat:
-				if( length == sizeof(float) ) fprintf(log_file, "float");
-				else if( length == sizeof(double) ) fprintf(log_file, "double");
-				else if( length == sizeof(long double) ) fprintf(log_file, "long double");
-				else fprintf(log_file, "<float%d>", length*8);
-				break;
-			default: fprintf(log_file, "<TODO name of basetype %d %d>", basetype, length); break;
-			}
-		}
-		break;
-	case SymTagPointerType:
-		{
-			DWORD subtype;
-			DWORD subtag;
-
-			if( !SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_TYPE, &subtype) )
-				fprintf(log_file, "<type not found>*");
-			else if( !SymGetTypeInfo_(hProcess, modBase, subtype, TI_GET_SYMTAG, &subtag) )
-				fprintf(log_file, "<symtag not found>*");
-			else
-			{
-				Dhp__PrintTypeName(subtype, subtag, FALSE, interData);
-				fprintf(log_file, "*");
-			}
-		}
-		break;
-	case SymTagArrayType:
-		{
-			DWORD childTypeIndex;
-			DWORD childSymtag;
-
-			// print root type
-			childTypeIndex = typeIndex;
-			childSymtag = symtag;
-			for( ; ; )
-			{
-				if( !SymGetTypeInfo_( hProcess, modBase, childTypeIndex, TI_GET_TYPE, &childTypeIndex) )
-				{
-					fprintf(log_file, "<child type not found>");
-					break;
-				}
-				if( !SymGetTypeInfo_( hProcess, modBase, childTypeIndex, TI_GET_SYMTAG, &childSymtag) )
-				{
-					fprintf(log_file, "<child symtag not found>");
-					break;
-				}
-				if( childSymtag != SymTagArrayType )
-				{
-					Dhp__PrintTypeName(childTypeIndex, childSymtag, FALSE, interData);
-					break;
-				}
-				// next dimension
-			}
-			// print dimensions
-			childTypeIndex = typeIndex;
-			childSymtag = symtag;
-			for( ; childSymtag == SymTagArrayType ; )
-			{
-				DWORD childCount;
-				if( !SymGetTypeInfo_( hProcess, modBase, childTypeIndex, TI_GET_COUNT, &childCount) )
-					fprintf(log_file, "[<count not found>]");
-				else
-					fprintf(log_file, "[%u]", childCount);
-				if( !SymGetTypeInfo_( hProcess, modBase, childTypeIndex, TI_GET_TYPE, &childTypeIndex) )
-				{
-					fprintf(log_file, "<child type not found>");
-					break;
-				}
-				if( !SymGetTypeInfo_( hProcess, modBase, childTypeIndex, TI_GET_SYMTAG, &childSymtag) )
-				{
-					fprintf(log_file, "<child symtag not found>");
-					break;
-				}
-				// next dimension
-			}
-		}
-		break;
-	default:
-		{
-			WCHAR* pSymname;
-			DWORD udtkind;
-
-			if( SymGetTypeInfo_( hProcess, modBase, typeIndex, TI_GET_UDTKIND, &udtkind) )
-			{
-				switch( (UdtKind)udtkind )
-				{
-				case UdtStruct: fprintf(log_file, "struct "); break;
-				case UdtClass: fprintf(log_file, "class "); break;
-				case UdtUnion: fprintf(log_file, "union "); break;
-				default: fprintf(log_file, "<unknown udtkind %d> ", udtkind); break;
-				}
-			}
-			if( SymGetTypeInfo_( hProcess, modBase, typeIndex, TI_GET_SYMNAME, &pSymname ) )
-			{
-				fprintf(log_file, "%ls", pSymname);
-				LocalFree( pSymname );
-			}
-			else
-				fprintf(log_file, "<TODO typename of symtag %d>", symtag); break;
-		}
-		break;
-	}
-
-	if( withParens )
-		fprintf(log_file, ")");
-}
-
-
-/// Prints the bytes in the target location.
-///
-/// @param log_file Log file
-/// @param p Pointer to the data
-/// @param length Length of the data in bytes
-static VOID
-Dhp__PrintValueBytes(
-	FILE*   log_file,
-	BYTE*   p,
-	ULONG64 length)
-{
-	ULONG64 i;
-
-	fprintf(log_file, "<bytes:");
-	for( i = 0; i < length; ++i )
-	{
-		fprintf(log_file, "%02X", p[i]);
-	}
-	fprintf(log_file, ">");
-}
-
-
-/// Prints a wide string/char value.
-///
-/// @param log_file Log file
-/// @param p Pointer to the value
-/// @param length Length of the value in bytes
-static VOID
-Dhp__PrintValueWideChars(
-	FILE*   log_file,
-	WCHAR*  wstr,
-	ULONG64 length,
-	BOOL    isString)
-{
-	ULONG64 i;
-	char* buf;
-	char delim;
-
-	length /= sizeof(WCHAR);
-	delim = ( isString || length > 1 ? '\"' : '\'' );
-	fprintf(log_file, "%c", delim);
-	buf = (char *)LocalAlloc(LMEM_FIXED, MB_CUR_MAX+1);
-	buf[MB_CUR_MAX] = '\0';
-	for( i = 0; i < length; ++i )
-	{
-		int n;
-		switch( wstr[i] )
-		{
-		case L'\"': fprintf(log_file, "\\\""); break;
-		case L'\'': fprintf(log_file, "\\\'"); break;
-		case L'\\': fprintf(log_file, "\\\\"); break;
-		case L'\a': fprintf(log_file, "\\a"); break;
-		case L'\b': fprintf(log_file, "\\b"); break;
-		case L'\f': fprintf(log_file, "\\f"); break;
-		case L'\n': fprintf(log_file, "\\n"); break;
-		case L'\r': fprintf(log_file, "\\r"); break;
-		case L'\t': fprintf(log_file, "\\t"); break;
-		case L'\v': fprintf(log_file, "\\v"); break;
-		default:
-			if( iswprint(wstr[i]) && (n=wctomb(buf, wstr[i])) > 0 )
-			{
-				buf[n] = '\0';
-				fprintf(log_file, "%s", buf);
-			}
-			else fprintf(log_file, "\\u%04X", wstr[i]);
-			break;
-		}
-	}
-	LocalFree(buf);
-	fprintf(log_file, "%c", delim);
-}
-
-
-/// Prints a string/char value.
-///
-/// @param log_file Log file
-/// @param p Pointer to the value
-/// @param length Length of the value in bytes
-static VOID
-Dhp__PrintValueChars(
-	FILE*   log_file,
-	char*   str,
-	ULONG64 length,
-	BOOL    isString)
-{
-	ULONG64 i;
-	char delim;
-
-	length /= sizeof(char);
-	delim = ( isString || length > 1 ? '\"' : '\'' );
-	fprintf(log_file, "%c", delim);
-	for( i = 0; i < length; ++i )
-	{
-		switch( str[i] )
-		{
-		case '\"': fprintf(log_file, "\\\""); break;
-		case '\'': fprintf(log_file, "\\\'"); break;
-		case '\\': fprintf(log_file, "\\\\"); break;
-		case '\a': fprintf(log_file, "\\a"); break;
-		case '\b': fprintf(log_file, "\\b"); break;
-		case '\f': fprintf(log_file, "\\f"); break;
-		case '\n': fprintf(log_file, "\\n"); break;
-		case '\r': fprintf(log_file, "\\r"); break;
-		case '\t': fprintf(log_file, "\\t"); break;
-		case '\v': fprintf(log_file, "\\v"); break;
-		default:
-			if( isprint((unsigned char)str[i]) ) fprintf(log_file, "%c", str[i]);
-			else fprintf(log_file, "\\x%02X", (unsigned char)str[i]);
-			break;
-		}
-	}
-	fprintf(log_file, "%c", delim);
-}
-
-
-/// Prints a float value.
-///
-/// @param log_file Log file
-/// @param p Pointer to the value
-/// @param length Length of the value in bytes
-static VOID
-Dhp__PrintValueFloat(
-	FILE*   log_file,
-	VOID*   p,
-	ULONG64 length)
-{
-	if( length == sizeof(float) ) fprintf(log_file, "%f", *(float*)p);
-	else if( length == sizeof(double) ) fprintf(log_file, "%lf", *(double*)p);
-	else if( length == sizeof(long double) ) fprintf(log_file, "%Lf", *(long double*)p);
-	else
-	{
-		fprintf(log_file, "<unexpected length %I64u>", length);
-		Dhp__PrintValueBytes(log_file, (BYTE*)p, length);
-	}
-}
-
-
-/// Prints a hex value.
-///
-/// @param log_file Log file
-/// @param p Pointer to the value
-/// @param length Length of the value in bytes
-static VOID
-Dhp__PrintValueHex(
-	FILE*   log_file,
-	VOID*   p,
-	ULONG64 length)
-{
-	if( length == sizeof(UINT32) ) fprintf(log_file, "0x%I32X", *(UINT32*)p);
-	else if( length == sizeof(UINT64) ) fprintf(log_file, "0x%I64X", *(UINT64*)p);
-	else if( length == sizeof(char) ) fprintf(log_file, "0x%X", *(unsigned char*)p);
-	else if( length == sizeof(short) ) fprintf(log_file, "0x%X", *(unsigned short*)p);
-	else if( length == sizeof(int) ) fprintf(log_file, "0x%x", *(unsigned int*)p);
-	else if( length == sizeof(long) ) fprintf(log_file, "0x%lX", *(unsigned long*)p);
-	else if( length == sizeof(long long) ) fprintf(log_file, "0x%llX", *(unsigned long long*)p);
-	else
-	{
-		fprintf(log_file, "<unexpected length %I64u>", length);
-		Dhp__PrintValueBytes(log_file, (BYTE*)p, length);
-	}
-}
-
-
-/// Prints an unsigned integer value.
-///
-/// @param log_file Log file
-/// @param p Pointer to the value
-/// @param length Length of the value in bytes
-static VOID
-Dhp__PrintValueUnsigned(
-	FILE*   log_file,
-	VOID*   p,
-	ULONG64 length)
-{
-	if( length == sizeof(INT32) ) fprintf(log_file, "%I32u", *(INT32*)p);
-	else if( length == sizeof(INT64) ) fprintf(log_file, "%I64u", *(INT64*)p);
-	else if( length == sizeof(char) ) fprintf(log_file, "%u", *(unsigned char*)p);
-	else if( length == sizeof(short) ) fprintf(log_file, "%u", *(unsigned short*)p);
-	else if( length == sizeof(int) ) fprintf(log_file, "%u", *(unsigned int*)p);
-	else if( length == sizeof(long) ) fprintf(log_file, "%lu", *(unsigned long*)p);
-	else if( length == sizeof(long long) ) fprintf(log_file, "%llu", *(unsigned long long*)p);
-	else
-	{
-		fprintf(log_file, "<unexpected length %I64u>", length);
-		Dhp__PrintValueBytes(log_file, (BYTE*)p, length);
-	}
-}
-
-
-/// Prints a signed integer value.
-///
-/// @param log_file Log file
-/// @param p Pointer to the value
-/// @param length Length of the value in bytes
-static VOID
-Dhp__PrintValueSigned(
-	FILE*   log_file,
-	VOID*   p,
-	ULONG64 length)
-{
-	if( length == sizeof(INT32) ) fprintf(log_file, "%I32d", *(INT32*)p);
-	else if( length == sizeof(INT64) ) fprintf(log_file, "%I64d", *(INT64*)p);
-	else if( length == sizeof(char) ) fprintf(log_file, "%d", *(signed char*)p);
-	else if( length == sizeof(short) ) fprintf(log_file, "%d", *(signed short*)p);
-	else if( length == sizeof(int) ) fprintf(log_file, "%d", *(signed int*)p);
-	else if( length == sizeof(long) ) fprintf(log_file, "%ld", *(signed long*)p);
-	else if( length == sizeof(long long) ) fprintf(log_file, "%lld", *(signed long long*)p);
-	else
-	{
-		fprintf(log_file, "<unexpected length %I64u>", length);
-		Dhp__PrintValueBytes(log_file, (BYTE*)p, length);
-	}
-}
-
-
-/// Prints a nul-terminated wide string value.
-/// Checks if the memory can be read from.
-///
-/// @param log_file Log file
-/// @param str Target string
-static VOID
-Dhp__PrintValueCWideString(
-	FILE*   log_file,
-	WCHAR*   str)
-{
-	ULONG64 length = 0;
-
-	// check if memory is readable
-	__try
-	{
-		while( str[length] != L'\0' )
-			++length;
-	}
-	__except( EXCEPTION_EXECUTE_HANDLER )
-	{
-		if( length ) Dhp__PrintValueWideChars(log_file, str, length*sizeof(WCHAR), TRUE);	// print readable part
-		fprintf(log_file, "<invalid memory>");
-		return;
-	}
-
-	// print string
-	Dhp__PrintValueWideChars(log_file, str, length*sizeof(WCHAR), TRUE);
-}
-
-
-/// Prints a nul-terminated string value.
-/// Checks if the memory can be read from.
-///
-/// @param log_file Log file
-/// @param str Target string
-static VOID
-Dhp__PrintValueCString(
-	FILE*   log_file,
-	char*   str)
-{
-	ULONG64 length = 0;
-
-	assert( log_file != NULL );
-
-	// check if memory is readable
-	__try
-	{
-		while( str[length] != '\0' )
-			++length;
-	}
-	__except( EXCEPTION_EXECUTE_HANDLER )
-	{
-		if( length ) Dhp__PrintValueChars(log_file, str, length*sizeof(char), TRUE);	// print readable part
-		fprintf(log_file, "<invalid memory>");
-		return;
-	}
-
-	// print string
-	Dhp__PrintValueChars(log_file, str, length*sizeof(char), TRUE);
-}
-
-
-// forward declaration of Dhp__PrintDataContents
-static VOID Dhp__PrintDataContents(DWORD typeIndex, PVOID pVariable, InterData*  interData);
-
-
-/// Prints the value of the data symbol.
-/// Checks if the memory can be read from.
-///
-/// @param typeIndex Type index of the symbol
-/// @param symtag Symbol tag
-/// @param pVariable Address to the symbol contents
-/// @param pInterData Inter data
-static VOID
-Dhp__PrintDataValue(
-	DWORD       typeIndex,
-	DWORD       symtag,
-	PVOID       pVariable,
-	InterData*  pInterData)
-{
-	// inter data
-	FILE* log_file;
-	DWORD64 modBase;
-	HANDLE hProcess;
-	//
-	ULONG64 length = 0;
-	DWORD basetype;
-	BOOL isValid = TRUE;
-
-	assert( pInterData != NULL );
-	log_file = pInterData->log_file;
-	modBase  = pInterData->modBase;
-	hProcess = pInterData->hProcess;
-
-	if( !SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_LENGTH, &length) )
-	{
-		fprintf(log_file, "<unknown data length>");
-		return;
-	}
-
-	// check if memory is readable
-	__try
-	{
-		BYTE* p = (BYTE*)pVariable;
-		ULONG i;
-		BYTE b = 0;
-		for( i = 0; i < length; ++i )
-			b += p[i];	// add to make sure it's not optimized out in release mode
-	}
-	__except( EXCEPTION_EXECUTE_HANDLER )
-	{
-		fprintf(log_file, "<invalid memory>");
-		return;
-	}
-
-	switch( symtag )
-	{
-	case SymTagBaseType:
-		{
-			if( !SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_BASETYPE, &basetype) )
-			{
-				fprintf(log_file, "<basetype not found>");
-				Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length);
-				break;
-			}
-			switch( basetype )
-			{
-			case btInt:
-			case btLong:
-				Dhp__PrintValueSigned(log_file, pVariable, length);
-				break;
-			case btUInt:
-			case btULong:
-				Dhp__PrintValueUnsigned(log_file, pVariable, length);
-				break;
-			case btFloat:
-				Dhp__PrintValueFloat(log_file, pVariable, length);
-				break;
-			case btChar:
-				{
-					if( length == sizeof(char) ) fprintf(log_file, "%u ", *(unsigned char*)pVariable);
-					Dhp__PrintValueChars(log_file, (char*)pVariable, length, FALSE);
-				}
-				break;
-			case btWChar:
-				{
-					if( length == sizeof(WCHAR) ) fprintf(log_file, "%u ", *(WCHAR*)pVariable);
-					Dhp__PrintValueWideChars(log_file, (WCHAR*)pVariable, length, FALSE);
-				}
-				break;
-			case btVoid:
-				if( length > 0 ) Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length);
-				break;
-			default:
-				fprintf(log_file, "<TODO value of basetype %d>", basetype);
-				Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length);
-				break;
-			}
-		}
-		break;
-	case SymTagEnum:
-		Dhp__PrintValueHex(log_file, pVariable, length);
-		break;
-	case SymTagPointerType:
-		{
-			DWORD childTypeIndex;
-			DWORD childSymtag;
-
-			fprintf(log_file, "0x%p", *(void**)pVariable);
-			if( SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_TYPE, &childTypeIndex) &&
-				SymGetTypeInfo_(hProcess, modBase, childTypeIndex, TI_GET_SYMTAG, &childSymtag) && 
-				childSymtag != SymTagPointerType )
-			{
-				DWORD childBasetype;
-
-				// child isn't a pointer, print the contents
-				fprintf(log_file, " ");
-				if( childSymtag == SymTagBaseType &&
-					SymGetTypeInfo_(hProcess, modBase, childTypeIndex, TI_GET_BASETYPE, &childBasetype) &&
-					(childBasetype == btChar || childBasetype == btWChar) )
-				{
-					// string or wide string
-					if( childBasetype == btChar ) Dhp__PrintValueCString(log_file, *(char**)pVariable);
-					else if( childBasetype == btWChar ) Dhp__PrintValueCWideString(log_file, *(WCHAR**)pVariable);
-					else fprintf(log_file, "<unexpected child basetype %d>", childBasetype);
-					break;
-				}
-				Dhp__PrintDataValue(childTypeIndex, childSymtag, *(PVOID*)pVariable, pInterData);
-			}
-		}
-		break;
-	case SymTagArrayType:
-		{
-			DWORD childTypeIndex;
-			DWORD childSymtag;
-			DWORD count;
-			DWORD i;
-
-			if( !SymGetTypeInfo_( hProcess, modBase, typeIndex, TI_GET_TYPE, &childTypeIndex) )
-			{
-				fprintf(log_file, "<child type not found>");
-				Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length);
-				break;
-			}
-			if( !SymGetTypeInfo_( hProcess, modBase, childTypeIndex, TI_GET_SYMTAG, &childSymtag) )
-			{
-				fprintf(log_file, "<child symtag not found>");
-				Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length);
-				break;
-			}
-			if( !SymGetTypeInfo_( hProcess, modBase, typeIndex, TI_GET_COUNT, &count) )
-			{
-				fprintf(log_file, "<count not found>");
-				Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length);
-				break;
-			}
-			// print values
-			fprintf(log_file, "{");
-			for( i = 0; i < count; ++i )
-			{
-				BYTE* pData = pVariable;
-				pData += i*(length/count);
-				if( i > 0 ) fprintf(log_file, ",");
-				Dhp__PrintDataValue(childTypeIndex, childSymtag, pData, pInterData);
-			}
-			fprintf(log_file, "}");
-		}
-		break;
-	default:
-#if 0
-		{//## TODO show children of structs/unions
-			TI_FINDCHILDREN_PARAMS* children;
-			DWORD childCount;
-			DWORD i;
-
-			// count children
-			if( !SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_CHILDRENCOUNT, &childCount) )
-			{
-				fprintf(log_file, "<child count not found>");
-				Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length);
-				break;
-			}
-
-			// Prepare to get an array of "TypeIds", representing each of the children.
-			// SymGetTypeInfo(TI_FINDCHILDREN) expects more memory than just a
-			// TI_FINDCHILDREN_PARAMS struct has.  Use derivation to accomplish this.
-			children = (TI_FINDCHILDREN_PARAMS*)LocalAlloc(LMEM_FIXED, sizeof(TI_FINDCHILDREN_PARAMS)+childCount*sizeof(ULONG));
-			children->Count = childCount;
-			children->Start= 0;
-
-			// Get the array of TypeIds, one for each child type
-			if( !SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_FINDCHILDREN, &children) )
-			{
-				fprintf(log_file, "<children not found>");
-				Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length);
-				LocalFree(children);
-				return;
-			}
-
-			// Iterate through each of the children
-			fprintf(log_file, "{");
-			for( i = 0; i < childCount; ++i )
-			{
-				DWORD childOffset;
-				DWORD childTypeid;
-				WCHAR* childName;
-				DWORD_PTR pData;
-
-				if( i > 0 ) fprintf(log_file, ",");
-
-				// Get the offset of the child member, relative to its parent
-				if( !SymGetTypeInfo_(hProcess, modBase, children->ChildId[i], TI_GET_OFFSET, &childOffset) )
-				{
-					fprintf(log_file, "<child offset not found>");
-					continue;
-				}
-
-				// Get the real "TypeId" of the child.
-				if( !SymGetTypeInfo_(hProcess, modBase, children->ChildId[i], TI_GET_TYPEID, &childTypeid) )
-				{
-					fprintf(log_file, "<child typeid not found>");
-					continue;
-				}
-
-				// Calculate the address of the member
-				pData = (DWORD_PTR)pVariable;
-				pData += childOffset;
-
-				// print name of the child
-				if( !SymGetTypeInfo_(hProcess, modBase, childTypeid, TI_GET_SYMNAME, &childName) )
-				{
-					fprintf(log_file, "<child symname not found>");
-					continue;
-				}
-				fprintf(log_file, "%ws=", childName);
-				LocalFree(childName);
-
-				// print contents of the child
-				Dhp__PrintDataContents(childTypeid, (PVOID)pData, interData);
-			}
-			fprintf(log_file, "}");
-
-			LocalFree(children);
-		}
-#endif
-		Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length);
-		break;
-	}
-}
-
-
-/// Prints the contents of the data symbol. (type and value)
-///
-/// @param typeIndex Type index of the symbol
-/// @param pVariable Address of the symbol contents
-/// @param pInterData Inter data
-static VOID
-Dhp__PrintDataContents(
-	DWORD typeIndex,
-	PVOID pVariable,
-	InterData*  pInterData)
-{
-	// inter data
-	FILE* log_file;
-	HANDLE hProcess;
-	DWORD64 modBase;
-	//
-	DWORD symtag;
-
-	assert( pInterData != NULL );
-	log_file = pInterData->log_file;
-	hProcess = pInterData->hProcess;
-	modBase  = pInterData->modBase;
-
-	if( SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_SYMTAG, &symtag) )
-	{
-		// print type
-		Dhp__PrintTypeName(typeIndex, symtag, TRUE, pInterData);
-		// print value
-		Dhp__PrintDataValue(typeIndex, symtag, pVariable, pInterData);
-	}
-	else
-		fprintf(log_file, "<symtag not found>");
-}
-
-
-/// Prints information about the data symbol.
-///
-/// @param pSymInfo Symbol info
-/// @param pInterData Inter data
-static VOID
-Dhp__PrintDataInfo(
-	PSYMBOL_INFO    pSymInfo,
-	InterData*      pInterData)
-{
-	// inter data
-	FILE* log_file;
-	STACKFRAME* pStackframe;
-	BOOL as_arg_list;
-	BOOL log_params;
-	BOOL log_locals;
-	BOOL log_globals;
-	int nr_of_var;
-	// my data
-	DWORD_PTR pVariable = 0;
-	enum{ UNKNOWN, PARAM, LOCAL, GLOBAL } scope = UNKNOWN;
-
-	assert( pSymInfo != NULL );
-	assert( pInterData != NULL );
-	assert( pSymInfo->Tag == SymTagData );
-	log_file    = pInterData->log_file;
-	pStackframe = pInterData->pStackframe;
-	as_arg_list = pInterData->as_arg_list;
-	log_params  = pInterData->log_params;
-	log_locals  = pInterData->log_locals;
-	log_globals = pInterData->log_globals;
-	nr_of_var   = pInterData->nr_of_var;
-
-	// Determine the scope and address of the variable
-    if( pSymInfo->Flags & SYMFLAG_REGREL )
-	{
-		pVariable = pStackframe->AddrFrame.Offset;
-		pVariable += (DWORD_PTR)pSymInfo->Address;
-		if( pSymInfo->Flags & SYMFLAG_PARAMETER )
-			scope = PARAM;	// parameter
-		else if( pSymInfo->Flags & SYMFLAG_LOCAL )
-		{
-			scope = LOCAL;	// local
-#if defined(_M_IX86)
-			if( (LONG64)pSymInfo->Address  > 0) scope = PARAM;	// parameter as local (bug in DBGHELP 5.1)
-#endif
-		}
-	}
-	else if( pSymInfo->Flags & SYMFLAG_REGISTER )
-	{
-		scope = ( pSymInfo->Flags & SYMFLAG_PARAMETER ? PARAM : LOCAL );	// register, optimized out(?)
-	}
-	else
-	{
-		pVariable = (DWORD_PTR)pSymInfo->Address;
-		scope = GLOBAL;	// It must be a global variable
-	}
-
-	// check if we should to log the variable
-	if( (scope == PARAM && log_params) ||
-		(scope == LOCAL && log_locals) ||
-		(scope == GLOBAL && log_globals) )
-	{
-		// print prefix and name
-		if( as_arg_list )
-			fprintf(log_file, "%s%s=", (nr_of_var ? ", " : ""), pSymInfo->Name);
-		else
-			fprintf(log_file, "\t%s = ", pSymInfo->Name);
-
-		// print value
-		if( !(pSymInfo->Flags & SYMFLAG_REGREL) && (pSymInfo->Flags & SYMF_REGISTER) )
-			fprintf(log_file, "<value optimized out>");
-		else
-		{
-			pInterData->modBase = pSymInfo->ModBase;
-			Dhp__PrintDataContents(pSymInfo->TypeIndex, (PVOID)pVariable, pInterData);
-		}
-
-		// print postfix
-		if( !as_arg_list )
-			fprintf(log_file, "\n");
-		pInterData->nr_of_var = ++nr_of_var;
-	}
-}
-
-
-/// Prints information about the symbol.
-///
-/// @param pSymInfo Symbol info
-/// @param pInterData Inter data
-static VOID
-Dhp__PrintSymbolInfo(
-	PSYMBOL_INFO    pSymInfo,
-	InterData*      pInterData)
-{
-	assert( pSymInfo != NULL );
-	assert( pInterData != NULL );
-
-	switch( pSymInfo->Tag ) 
-	{
-	case SymTagData: Dhp__PrintDataInfo( pSymInfo, pInterData ); break; 
-	default: /*fprintf(pInterData->log_file, "<unsupported symtag %d>", pSymInfo->Tag);*/ break;
-	}
-}
-
-
-/// Prints the details of one symbol to the log file.
-/// Used as a callback for SymEnumSymbols.
-///
-/// @param pSymInfo Symbol info
-/// @param symSize Size of the symbol info structure
-/// @param pData Inter data
-static BOOL WINAPI
-Dhp__EnumSymbolsCallback(
-	PSYMBOL_INFO    pSymInfo,
-	ULONG           symSize,
-	PVOID           pData)
-{
-	if( pSymInfo == NULL )
-		return TRUE;	// try other symbols
-
-	if( pData == NULL )
-	{
-		printf("Dhp__EnumSymbolsCallback: pData is NULL\n");
-		return FALSE;
-	}
-
-	Dhp__PrintSymbolInfo(pSymInfo, (InterData*)pData);
-	return TRUE;
-}
-
-
-/// Prints the source code of the target line.
-/// Searches for the target file in the original path,
-/// in the last src folder of the original path (relative)
-/// and in the current directory.
-///
-/// @param filename Original source file
-/// @param line Target line
-/// @param log_file Log file
-static VOID
-Dhp__PrintSourceLine(
-	FILE* log_file,
-	char* filename,
-	DWORD line)
-{
-	char path[MAX_PATH*3];
-	char pathBuffer[MAX_PATH+1];
-	char* p;
-
-	assert( filename != NULL );
-	assert( log_file != NULL );
-
-	// generate search paths
-	strcpy(path, filename);	// original path
-	p = strrchr(path, '\\');
-	if( p )
-	{
-		memcpy(p, ";\0", 2);
-		p = strstr(filename, "\\src\\");
-		if( p )
-		{
-			while( strstr(p+1, "\\src\\") )
-				p = strstr(p+1, "\\src\\");
-			strcat(path, p+1);	// last src folder path
-			p = strrchr(path, '\\');
-			memcpy(p, ";\0", 2);
-		}
-		filename = strrchr(filename, '\\')+1;
-	}
-	else
-		*path = '\0';	// no path
-	strcat(path, ".");	// current directoy
-
-	// search for file and line
-	if( SearchPathA(path, filename, NULL, MAX_PATH, pathBuffer, NULL) )
-	{
-		char code[1024+1];
-		DWORD i = 1;
-		FILE* fp;
-
-		fp = fopen(pathBuffer, "rt");
-		if( fp == NULL )
-			return;
-
-		code[1024] = '\0';
-		while( fgets(code, 1024, fp) )
-		{
-			if( i == line )
-			{// found line
-				char* term = strchr(code, '\n');
-				if( term && term != code && term[-1] == '\r' ) --term;
-				if( term ) *term = '\0';
-				fprintf(log_file, "%d\t%s\n", line, code);
-				break;
-			}
-			if( strchr(code, '\n') )
-				++i;
-		}
-		fclose(fp);
-	}
-}
-
-
-/// Prints details of one function to the log file.
-///
-/// @param interData Inter data
-static VOID
-Dhp__PrintFunctionDetails(
-	InterData*  pInterData)
-{
-	// inter data
-	HANDLE hProcess;
-	STACKFRAME* pStackframe;
-	FILE* log_file;
-	int nr_of_frame;
-	//
-	PSYMBOL_INFO pSymbolInfo;
-	DWORD64 funcDisplacement=0;
-	IMAGEHLP_STACK_FRAME imagehlpStackFrame;
-	IMAGEHLP_LINE imagehlpLine;
-	DWORD lineDisplacement=0;
-
-	assert( pInterData != NULL );
-	hProcess    = pInterData->hProcess;
-	pStackframe = pInterData->pStackframe;
-	log_file    = pInterData->log_file;
-	nr_of_frame = pInterData->nr_of_frame;
-
-	// frame info
-	fprintf(log_file,
-		"#%d  0x%p",
-		nr_of_frame, (void*)(DWORD_PTR)pStackframe->AddrPC.Offset);
-
-	// restrict symbol enumeration to this frame only
-	ZeroMemory(&imagehlpStackFrame, sizeof(IMAGEHLP_STACK_FRAME));
-	imagehlpStackFrame.InstructionOffset = pStackframe->AddrPC.Offset;
-	SymSetContext_(hProcess, &imagehlpStackFrame, 0);
-
-	// function name and displacement
-	pSymbolInfo = (PSYMBOL_INFO)LocalAlloc(LMEM_FIXED, sizeof(SYMBOL_INFO)+1024);
-	pSymbolInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
-	pSymbolInfo->MaxNameLen = 1024;
-	if( SymFromAddr_(hProcess, pStackframe->AddrPC.Offset, &funcDisplacement, pSymbolInfo) == TRUE )
-	{
-		fprintf(log_file,
-			" in %.1024s+0x%I64X (",
-			pSymbolInfo->Name, funcDisplacement);
-
-		// log all function parameters
-		pInterData->as_arg_list = TRUE;
-		pInterData->log_params = TRUE;
-		pInterData->log_locals = FALSE;
-		pInterData->log_globals = FALSE;
-		pInterData->nr_of_var = 0;
-		SymEnumSymbols_(hProcess, 0, 0, Dhp__EnumSymbolsCallback, pInterData);
-
-		fprintf(log_file,
-			")");
-	}
-	else
-		fprintf(log_file,
-			"in <unknown function>");
-
-	// find the source line for this function.
-	imagehlpLine.SizeOfStruct = sizeof(IMAGEHLP_LINE);
-	if( SymGetLineFromAddr_(hProcess, pStackframe->AddrPC.Offset, &lineDisplacement, &imagehlpLine) != 0 )
-	{
-		char* filename = imagehlpLine.FileName;
-		DWORD line = imagehlpLine.LineNumber;
-
-		fprintf(log_file,
-			" at %s:%d\n",
-			filename, line);
-
-		Dhp__PrintSourceLine(log_file, filename, line);
-	}
-	else
-		fprintf(log_file,
-			"\n");
-
-	// log all function local variables
-	pInterData->as_arg_list = FALSE;
-	pInterData->log_params = FALSE;
-	pInterData->log_locals = TRUE;
-	pInterData->log_globals = FALSE;
-	pInterData->nr_of_var = 0;
-	SymEnumSymbols_(hProcess, 0, 0, Dhp__EnumSymbolsCallback, pInterData);
-
-	pInterData->nr_of_frame = ++nr_of_frame;
-	LocalFree(pSymbolInfo);
-}
-
-
-/// Walks over the stack and prints all relevant information to the log file.
-///
-/// @param context Exception context
-/// @param log_file Log file
-static VOID
-Dhp__PrintStacktrace(
-	CONTEXT *context,
-	FILE *log_file)
-{
-	HANDLE hProcess = GetCurrentProcess();
-	STACKFRAME stackframe;
-	DWORD machine;
-	CONTEXT ctx;
-	InterData interData;
-	int skip = 0;
-	int i;
-
-	assert( log_file != NULL );
-
-	fprintf(log_file,
-		"\nStacktrace:\n");
-
-	// Use thread information - if not supplied.
-	if( context == NULL )
-	{
-		// If no context is supplied, skip 1 frame
-		skip = 1;
-
-		ctx.ContextFlags = CONTEXT_FULL;
-		if( GetThreadContext(GetCurrentThread(), &ctx) )
-			context = &ctx;
-	}
-
-	if( context == NULL )
-		return;
-
-	// Write the stack trace
-	ZeroMemory(&stackframe, sizeof(STACKFRAME));
-	stackframe.AddrPC.Mode = AddrModeFlat;
-	stackframe.AddrStack.Mode = AddrModeFlat;
-	stackframe.AddrFrame.Mode = AddrModeFlat;
-#if defined(_M_IX86)
-	machine = IMAGE_FILE_MACHINE_I386;
-	stackframe.AddrPC.Offset = context->Eip;
-	stackframe.AddrStack.Offset = context->Esp;
-	stackframe.AddrFrame.Offset = context->Ebp;
-#else /* defined(_M_IX86) */
-#error FIXME add more processors
-some compilers don't stop on #error, this line makes sure it errors out
-#endif
-
-	interData.hProcess = hProcess;
-	interData.log_file = log_file;
-	interData.pStackframe = &stackframe;
-	interData.nr_of_frame = 0;
-	for( i = 0; ; ++i )
-	{
-		if( !StackWalk_(machine, hProcess, GetCurrentThread(),
-			&stackframe, context, NULL, SymFunctionTableAccess_,
-			SymGetModuleBase_, NULL))
-		{
-			break;
-		}
-
-		if( i >= skip )
-		{
-			// Check that the address is not zero.
-			// Sometimes StackWalk returns TRUE with a frame of zero.
-			if( stackframe.AddrPC.Offset != 0 )
-				Dhp__PrintFunctionDetails(&interData);
-		}
-	}
-}
-
-
-typedef BOOL (WINAPI *ISDEBUGGERPRESENT)(void);
-/// Checks if a debugger is attached to this process
-///
-/// @return TRUE is a debugger is present
-static BOOL
-Dhp__IsDebuggerPresent()
-{
-	HANDLE kernel32_dll;
-	ISDEBUGGERPRESENT IsDebuggerPresent_;
-	BOOL result;
-
-	kernel32_dll = LoadLibraryA("kernel32.dll");
-	if( kernel32_dll == NULL )
-		return FALSE;
-
-	IsDebuggerPresent_ = (ISDEBUGGERPRESENT)GetProcAddress(kernel32_dll, "IsDebuggerPresent");
-	if( IsDebuggerPresent_ )
-		result = IsDebuggerPresent_();
-	else
-		result = FALSE;
-
-	FreeLibrary(kernel32_dll);
-
-	return result;
-}
-
-
-/// Loads the dbghelp.dll library.
-///
-/// @return TRUE is sucessfull
-static BOOL
-Dhp__LoadDbghelpDll()
-{
-	dbghelp_dll = LoadLibraryA(DBGHELP_DLL);
-	if( dbghelp_dll != INVALID_HANDLE_VALUE )
-	{
-		DWORD opts;
-
-		// load the functions
-		MiniDumpWriteDump_      =      (MINIDUMPWRITEDUMP)GetProcAddress(dbghelp_dll, "MiniDumpWriteDump");
-		SymInitialize_          =          (SYMINITIALIZE)GetProcAddress(dbghelp_dll, "SymInitialize");
-		SymSetOptions_          =          (SYMSETOPTIONS)GetProcAddress(dbghelp_dll, "SymSetOptions");
-		SymGetOptions_          =          (SYMGETOPTIONS)GetProcAddress(dbghelp_dll, "SymGetOptions");
-		SymCleanup_             =             (SYMCLEANUP)GetProcAddress(dbghelp_dll, "SymCleanup");
-		SymGetTypeInfo_         =         (SYMGETTYPEINFO)GetProcAddress(dbghelp_dll, "SymGetTypeInfo");
-		SymGetLineFromAddr_     =     (SYMGETLINEFROMADDR)GetProcAddress(dbghelp_dll, "SymGetLineFromAddr");
-		SymEnumSymbols_         =         (SYMENUMSYMBOLS)GetProcAddress(dbghelp_dll, "SymEnumSymbols");
-		SymSetContext_          =          (SYMSETCONTEXT)GetProcAddress(dbghelp_dll, "SymSetContext");
-		SymFromAddr_            =            (SYMFROMADDR)GetProcAddress(dbghelp_dll, "SymFromAddr");
-		StackWalk_              =              (STACKWALK)GetProcAddress(dbghelp_dll, "StackWalk");
-		SymFunctionTableAccess_ = (SYMFUNCTIONTABLEACCESS)GetProcAddress(dbghelp_dll, "SymFunctionTableAccess");
-		SymGetModuleBase_       =       (SYMGETMODULEBASE)GetProcAddress(dbghelp_dll, "SymGetModuleBase");
-
-		if( MiniDumpWriteDump_ &&
-			SymInitialize_  && SymSetOptions_  && SymGetOptions_ &&
-			SymCleanup_     && SymGetTypeInfo_ && SymGetLineFromAddr_ &&
-			SymEnumSymbols_ && SymSetContext_  && SymFromAddr_ && StackWalk_ &&
-			SymFunctionTableAccess_ && SymGetModuleBase_ )
-		{
-			// initialize the symbol loading code
-			opts = SymGetOptions_();
-
-			// Set the 'load lines' option to retrieve line number information.
-			// Set the 'deferred loads' option to map the debug info in memory only when needed.
-			SymSetOptions_(opts | SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS);
-
-			// Initialize the dbghelp DLL with the default path and automatic
-			// module enumeration (and loading of symbol tables) for this process.
-			SymInitialize_(GetCurrentProcess(), NULL, TRUE);
-
-			return TRUE;
-		}
-	}
-
-	if( dbghelp_dll )
-	{
-		FreeLibrary(dbghelp_dll);
-		dbghelp_dll = NULL;
-	}
-
-	return FALSE;
-}
-
-
-/// Unloads the dbghelp.dll library.
-static VOID
-Dhp__UnloadDbghlpDll()
-{
-	SymCleanup_(GetCurrentProcess());
-
-	FreeLibrary(dbghelp_dll);
-	dbghelp_dll = NULL;
-}
-
-
-/// Creates the report and minidump files.
-/// Puts the resulting pathnames in the arguments.
-/// The buffers must be at least MAX_PATH+1 in size.
-///
-/// @param out_lpszLogFileName Buffer for the report filename
-/// @param out_lpszDmpFileName Buffer for the minidump filename
-/// @return TRUE if the files were created
-static BOOL
-Dhp__CreateFiles(
-	char*   out_logFileName,
-	char*   out_dmpFileName)
-{
-#define LEN_TIMESTAMP 14	// "YYYYMMDDhhmmss"
-#define LEN_EXT 4	// ".rpt" or ".dmp"
-	char baseFileName[MAX_PATH+1];
-	char timestamp[LEN_TIMESTAMP+1];
-	FILE* fp;
-	time_t now;
-
-	// Generate base filename for the report/minidump
-	ZeroMemory(baseFileName, sizeof(baseFileName));
-	if( GetModuleFileName(NULL, baseFileName, MAX_PATH-LEN_TIMESTAMP-LEN_EXT) )
-	{
-		char* pTerm = strrchr(baseFileName, '\\');
-		if( pTerm == NULL ) pTerm = baseFileName;
-		pTerm = strrchr(pTerm, '.');
-		if( pTerm ) *pTerm = '\0';	// remove extension
-	}
-	else if( GetTempPathA(MAX_PATH-6-LEN_TIMESTAMP-LEN_EXT, baseFileName) )
-	{// in temp folder
-		strcat(baseFileName, DBG_DEFAULT_FILENAME);
-	}
-	else
-	{// in current folder
-		strcpy(baseFileName, DBG_DEFAULT_FILENAME);
-	}
-
-	time(&now);
-#if 0
-	szTimestamp[0] = '\0';
-#else
-	strftime(timestamp, sizeof(timestamp), "%Y%m%d%H%M%S", localtime(&now));
-#endif
-	timestamp[LEN_TIMESTAMP] = '\0';
-	
-	sprintf(out_logFileName, "%s%s.rpt", baseFileName, timestamp);
-	fp = fopen(out_logFileName, "w");
-	if( fp == NULL )
-		return FALSE;	// failed to create log file
-	fclose(fp);
-
-	sprintf(out_dmpFileName, "%s%s.dmp", baseFileName, timestamp);
-	fp = fopen(out_dmpFileName, "w");
-	if( fp == NULL)
-		return FALSE;	// failed to create dump file
-	fclose(fp);
-
-	return TRUE;	// success
-#undef LEN_EXT
-#undef LEN_TIMESTAMP
-}
-
-
-/// Unhandled exception handler. Where the magic starts... ;D
-///
-/// @param ptrs Exception information
-/// @return What to do with the exception
-LONG WINAPI
-Dhp__UnhandledExceptionFilter(PEXCEPTION_POINTERS ptrs)
-{
-	char szLogFileName[MAX_PATH+1];
-	char szDmpFileName[MAX_PATH+1];
-	FILE* log_file;
-
-	// check if the crash handler was already loaded (crash while handling the crash)
-	if( dbghelp_dll != INVALID_HANDLE_VALUE )
-		return EXCEPTION_CONTINUE_SEARCH;
-
-	// don't log anything if we're running inside a debugger ...
-	if( Dhp__IsDebuggerPresent() == TRUE )
-		return EXCEPTION_CONTINUE_SEARCH;
-
-	// ... or if we can't load dbghelp.dll ...
-	if( Dhp__LoadDbghelpDll() == FALSE )
-		return EXCEPTION_CONTINUE_SEARCH;
-
-	// ... or if we can't create the log files
-	if( Dhp__CreateFiles(szLogFileName, szDmpFileName) == FALSE )
-		return EXCEPTION_CONTINUE_SEARCH;
-
-	// open log file
-	log_file = fopen(szLogFileName, "wt");
-
-	// print information about the process
-	Dhp__PrintProcessInfo(
-		ptrs ? ptrs->ExceptionRecord : NULL,
-		ptrs ? ptrs->ContextRecord : NULL,
-		log_file);
-
-	// print the stacktrace
-	Dhp__PrintStacktrace(
-		ptrs ? ptrs->ContextRecord : NULL,
-		log_file);
-
-	// write the minidump file and use the callback to print the list of modules to the log file
-	Dhp__WriteMinidumpFile(
-		szDmpFileName,
-		ptrs,
-		Dhp__PrintModuleInfoCallback,
-		log_file);
-
-	fclose(log_file);
-
-	Dhp__UnloadDbghlpDll();
-
-	// inform the user
-	fprintf(stderr,
-		"\n"
-		"This application has halted due to an unexpected error.\n"
-		"A crash report and minidump file were saved to disk, you can find them here:\n"
-		"%s\n"
-		"%s\n"
-		DBG_EXTENDED_INFORMATION
-		"\n"
-		"NOTE: The crash report and minidump files can contain sensitive information\n"
-		"(filenames, partial file content, usernames and passwords etc.)\n",
-		szLogFileName,
-		szDmpFileName);
-
-	// terminate the application
-	return EXCEPTION_EXECUTE_HANDLER;
-}
-
-
-
-/////////////////////////////////////////////////////////////////////
-// DLL stuff
-#if !defined(DBG_EMBEDDED)
-
-
-/// Previous exception filter.
-static LPTOP_LEVEL_EXCEPTION_FILTER previousFilter;
-
-
-#if defined(__GNUC__)
-// GNU : define DLL load/unload functions
-static void Dhp__OnStartup(void) __attribute__((constructor));
-static void Dhp__OnExit(void) __attribute__((destructor));
-#endif /* defined(__GNUC__) */
-
-
-/// Installs as the unhandled exception handler.
-void Dhp__OnStartup(void)
-{
-	// Install the unhandled exception filter function
-	previousFilter = SetUnhandledExceptionFilter(Dhp__UnhandledExceptionFilter);
-}
-
-
-/// Uninstalls the handler.
-void Dhp__OnExit(void)
-{
-	SetUnhandledExceptionFilter(previousFilter);
-}
-
-
-#if !defined(__GNUC__)
-// Windows : invoke DLL load/unload functions
-BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
-{
-	switch( dwReason )
-	{
-		case DLL_PROCESS_ATTACH: Dhp__OnStartup(); break;
-		case DLL_PROCESS_DETACH: Dhp__OnExit(); break;
-	}
-	return TRUE;
-}
-#endif /* !defined(__GNUC__) */
-
-
-
-#endif /* !defined(DBG_EMBEDDED) */
-
-
-
-#endif /* _WIN32 */

+ 0 - 54
src/plugins/dbghelpplug.rc

@@ -1,54 +0,0 @@
-// BC++ has all the necessary preprocessor macros defined automatically
-#if !defined(__BORLANDC__)
-#include "winres.h"
-#endif // !defined(__BORLANDC__)
-
-#define VER_FILEVERSION             1,0,0,2
-#define VER_FILEVERSION_STR         "1.0.0.2\0"
-
-#define VER_PRODUCTVERSION          1,0,0,2
-#define VER_PRODUCTVERSION_STR      "1.0.0.2\0"
-
-#if defined(DEBUG) || defined(_DEBUG)
-#define VER_DEBUG                   0
-#else
-#define VER_DEBUG                   VS_FF_DEBUG
-#endif
-
-#define VER_COMMENTS_STR            "Registers as the unhandled exception handler. Generates reports and minidumps.\0"
-#define VER_COMPANYNAME_STR         "eAthena\0"
-#define VER_FILEDESCRIPTION_STR     "Stackdump Plugin by eAthena\0"
-#define VER_INTERNALNAME_STR        "dbghelpplug\0"
-#define VER_LEGALCOPYRIGHT_STR      "Copyright (C) 2008\0"
-#define VER_ORIGINALFILENAME_STR    "dbghelpplug.dll\0"
-#define VER_PRODUCTNAME_STR         "dbghelpplug\0"
-
-VS_VERSION_INFO VERSIONINFO
-FILEVERSION     VER_FILEVERSION
-PRODUCTVERSION  VER_PRODUCTVERSION
-FILEFLAGSMASK   VS_FFI_FILEFLAGSMASK
-FILEFLAGS       VER_DEBUG
-FILEOS          (VOS_NT|VOS__WINDOWS32)
-FILETYPE        VFT_DLL
-FILESUBTYPE     VFT2_UNKNOWN
-BEGIN
-    BLOCK "StringFileInfo"
-    BEGIN
-        BLOCK "040904E4"
-        BEGIN
-            VALUE "Comments",           VER_COMMENTS_STR
-            VALUE "CompanyName",        VER_COMPANYNAME_STR
-            VALUE "FileDescription",    VER_FILEDESCRIPTION_STR
-            VALUE "FileVersion",        VER_FILEVERSION_STR
-            VALUE "InternalName",       VER_INTERNALNAME_STR
-            VALUE "LegalCopyright",     VER_LEGALCOPYRIGHT_STR
-            VALUE "OriginalFilename",   VER_ORIGINALFILENAME_STR
-            VALUE "ProductName",        VER_PRODUCTNAME_STR
-            VALUE "ProductVersion",     VER_PRODUCTVERSION_STR
-        END
-    END
-    BLOCK "VarFileInfo"
-    BEGIN
-        VALUE "Translation", 0x0, 1200
-    END
-END

+ 0 - 53
src/plugins/pid.c

@@ -1,53 +0,0 @@
-
-#include <stdio.h>
-#include <string.h>
-
-#if !defined _WIN32 || defined MINGW
-	#include <unistd.h> // getpid(), unlink()
-#else
-	#include <windows.h>
-	#define getpid GetCurrentProcessId
-#endif
-
-#include "../common/plugin.h"
-
-PLUGIN_INFO = {
-	"ProcessId",
-	PLUGIN_ALL,
-	"1.0",
-	PLUGIN_VERSION,
-	"Logs the process ID"
-};
-
-PLUGIN_EVENTS_TABLE = {
-	{ "pid_create", "Plugin_Init" },
-	{ "pid_delete", "Plugin_Final" },
-	{ NULL, NULL }
-};
-
-char pid_file[256];
-char *server_name;
-
-void pid_create ()
-{
-	FILE *fp;
-	int len;
-	
-	IMPORT_SYMBOL(server_name, 1);
-	len = strlen(server_name);
-	strcpy(pid_file, server_name);
-	if(len > 4 && pid_file[len - 4] == '.') {
-		pid_file[len - 4] = 0;
-	}
-	strcat(pid_file, ".pid");
-	fp = fopen(pid_file, "w");
-	if (fp) {
-		fprintf(fp, "%d", getpid());
-		fclose(fp);
-	}
-}
-
-void pid_delete ()
-{
-	unlink(pid_file);
-}

+ 0 - 7
src/plugins/pid.def

@@ -1,7 +0,0 @@
-EXPORTS
-	plugin_info         DATA
-	plugin_event_table  DATA
-	plugin_call_table   DATA
-
-	pid_create
-	pid_delete

+ 0 - 77
src/plugins/sample.c

@@ -1,77 +0,0 @@
-// Sample Athena plugin
-
-#include <stdio.h>
-#include <string.h>
-#include "../common/plugin.h"
-
-////// Plugin information ////////
-//
-PLUGIN_INFO = {
-// change only the following area
-	"Test",			// Plugin name
-	PLUGIN_ALL,		// Which servers is this plugin for
-	"0.1",			// Plugin version
-	PLUGIN_VERSION,		// Minimum plugin engine version to run
-	"A sample plugin"	// Short description of plugin
-};
-
-////// Plugin event list //////////
-// Format: <plugin function>,<event name>
-// All registered functions to a event gets executed
-// (In descending order) when its called.
-// Multiple functions can be called by multiple events too,
-// So it's up to your creativity ^^
-//
-PLUGIN_EVENTS_TABLE = {
-// change only the following area
-	{ "test_me", "Plugin_Test" },	// when the plugin is tested for compatibility
-	{ "do_init", "Plugin_Init" },	// when plugins are loaded
-	{ "do_final", "Plugin_Final" },	// when plugins are unloaded
-	{ "some_function", "some_event" },
-	{ "some_function", "another_event" },
-	{ NULL, NULL }
-};
-
-///// Variables /////
-char *server_type;
-char *server_name;
-
-//////// Plugin functions //////////
-int do_init ()
-{
-	// import symbols from the server
-	IMPORT_SYMBOL(server_type, 0);
-	IMPORT_SYMBOL(server_name, 1);
-
-	printf ("Server type is ");
-	switch (*server_type) {
-		case PLUGIN_LOGIN: printf ("Login\n"); break;
-		case PLUGIN_CHAR: printf ("Char\n"); break;
-		case PLUGIN_MAP: printf ("Map\n"); break;
-	}
-	printf ("Filename is %s\n", server_name);
-
-	return 1;
-}
-
-int do_final ()
-{
-	printf ("Bye world\n");
-
-	return 1;
-}
-
-int some_function ()
-{
-	printf ("Some function\n");
-	return 0;
-}
-
-// return 1 if the testing passes, otherwise 0
-// (where the plugin will be deactivated)
-int test_me ()
-{
-	if (1 + 1 == 2)
-		return 1;
-	return 0;
-}

+ 0 - 11
src/plugins/sample.def

@@ -1,11 +0,0 @@
-EXPORTS
-	; common exports
-	plugin_info         DATA
-	plugin_event_table  DATA
-	plugin_call_table   DATA
-
-	; plugin-specific exports
-	test_me
-	do_init
-	do_final
-	some_function

+ 0 - 208
src/plugins/sig.c

@@ -1,208 +0,0 @@
-// $Id: sig.c 1 2005-6-13 3:17:17 PM Celestia $
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#define __USE_GNU  // required to enable strsignal on some platforms
-#include <string.h>
-#include <time.h>
-#include "../common/plugin.h"
-
-PLUGIN_INFO = {
-	"Signals",
-	PLUGIN_CORE,
-	"1.1",
-	PLUGIN_VERSION,
-	"Handles program signals"
-};
-
-PLUGIN_EVENTS_TABLE = {
-	{ "sig_init", "Plugin_Init" },
-	{ "sig_final", "Plugin_Final" },
-	{ NULL, NULL }
-};
-
-//////////////////////////////////////
-
-#if defined(_WIN32) || defined(MINGW)
-	int sig_init()
-	{
-		printf("sig: This plugin is not supported - Enable 'exchndl' instead!\n");
-		return 0;
-	}
-	int sig_final() { return 0; }
-#elif defined (__NETBSD__) || defined (__FREEBSD__)
-	int sig_init()
-	{
-		printf("sig: This plugin is not supported!\n");
-		return 0;
-	}
-	int sig_final() { return 0; }
-#else
-
-//////////////////////////////////////
-
-#if !defined(CYGWIN)
-	#include <execinfo.h>
-#endif
-
-const char* (*getrevision)();
-unsigned long (*getuptime)();
-char *server_name;
-int crash_flag = 0;
-
-int sig_final ();
-
-// by Gabuzomeu
-// This is an implementation of signal() using sigaction() for portability.
-// (sigaction() is POSIX; signal() is not.)  Taken from Stevens' _Advanced
-// Programming in the UNIX Environment_.
-//
-
-#ifndef POSIX
-#define compat_signal(signo, func) signal(signo, func)
-#else
-sigfunc *compat_signal(int signo, sigfunc *func)
-{
-	struct sigaction sact, oact;
-
-	sact.sa_handler = func;
-	sigemptyset(&sact.sa_mask);
-	sact.sa_flags = 0;
-#ifdef SA_INTERRUPT
-	sact.sa_flags |= SA_INTERRUPT;	/* SunOS */
-#endif
-
-	if (sigaction(signo, &sact, &oact) < 0)
-		return (SIG_ERR);
-
-	return (oact.sa_handler);
-}
-#endif
-
-/*=========================================
- *	Dumps the stack using glibc's backtrace
- *-----------------------------------------
- */
-#ifdef CYGWIN
-	#define FOPEN_ freopen
-	#ifdef __cplusplus
-	extern "C" void cygwin_stackdump();
-	#else
-	extern void cygwin_stackdump();
-	#endif
-	
-#else
-	#define FOPEN_(fn,m,s) fopen(fn,m)
-#endif
-void sig_dump(int sn)
-{
-	FILE *fp;
-	char file[256];
-	int no = 0;
-
-	crash_flag = 1;
-	// search for a usable filename
-	do {
-		sprintf (file, "log/%s%04d.stackdump", server_name, ++no);
-	} while((fp = fopen(file,"r")) && (fclose(fp), no < 9999));
-	// dump the trace into the file
-
-	if ((fp = FOPEN_(file, "w", stderr)) != NULL) {
-		const char *revision;
-	#ifndef CYGWIN
-		void* array[20];
-		char **stack;
-		size_t size;
-	#endif
-
-		printf ("sig: Dumping stack to '%s'...\n", file);
-		if ((revision = getrevision()) != NULL)
-			fprintf(fp, "Version: svn%s \n", revision);
-		fprintf(fp, "Exception: %s \n", strsignal(sn));
-		fflush (fp);
-
-	#ifdef CYGWIN
-		cygwin_stackdump ();
-	#else
-		fprintf(fp, "Stack trace:\n");
-		size = backtrace (array, 20);
-		stack = backtrace_symbols (array, size);
-		for (no = 0; no < size; no++) {
-			fprintf(fp, "%s\n", stack[no]);
-		}
-		fprintf(fp,"End of stack trace\n");
-		free(stack);
-	#endif
-
-		printf("sig: %s Saved.\n", file);
-		fflush(stdout);
-		fclose(fp);
-	}
-
-	sig_final();	// Log our uptime
-	// Pass the signal to the system's default handler
-	compat_signal(sn, SIG_DFL);
-	raise(sn);
-}
-
-/*=========================================
- *	Shutting down (Program did not crash ^^)
- *	- Log our current up time
- *-----------------------------------------
- */
-int sig_final ()
-{
-	time_t curtime;
-	char curtime2[24];
-	FILE *fp;
-	long seconds = 0, day = 24*60*60, hour = 60*60,
-		minute = 60, days = 0, hours = 0, minutes = 0;
-
-	fp = fopen("log/uptime.log","a");
-	if (fp) {
-		time(&curtime);
-		strftime(curtime2, 24, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
-
-		seconds = getuptime();
-		days = seconds/day;
-		seconds -= (seconds/day>0)?(seconds/day)*day:0;
-		hours = seconds/hour;
-		seconds -= (seconds/hour>0)?(seconds/hour)*hour:0;
-		minutes = seconds/minute;
-		seconds -= (seconds/minute>0)?(seconds/minute)*minute:0;
-
-		fprintf(fp, "%s: %s %s - %ld days, %ld hours, %ld minutes, %ld seconds.\n",
-			curtime2, server_name, (crash_flag ? "crashed" : "uptime"),
-			days, hours, minutes, seconds);
-		fclose(fp);
-	}
-
-	return 1;
-}
-
-/*=========================================
- *	Register the signal handlers
- *-----------------------------------------
- */
-int sig_init ()
-{
-	void (*func)(int) = sig_dump;
-#ifdef CYGWIN	// test if dumper is enabled
-	char *buf = getenv ("CYGWIN");
-	if (buf && strstr(buf, "error_start") != NULL)
-		func = SIG_DFL;
-#endif
-
-	IMPORT_SYMBOL(server_name, 1);
-	IMPORT_SYMBOL(getrevision, 6);
-	IMPORT_SYMBOL(getuptime, 11);
-
-	compat_signal(SIGSEGV, func);
-	compat_signal(SIGFPE, func);
-	compat_signal(SIGILL, func);
-	compat_signal(SIGBUS, func);
-
-	return 1;
-}
-#endif