diff --git a/handler/handler0vars.h b/handler/handler0vars.h
index bc9e9d25c2a..33b7ffb997a 100644
--- a/handler/handler0vars.h
+++ b/handler/handler0vars.h
@@ -1,53 +1,53 @@
-/***********************************************************************
-This file contains accessor functions for dynamic plugin on Windows.
-
-(c) 2008 Innobase Oy
-***********************************************************************/
-#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
-/***********************************************************************
-This is a list of externals that can not be resolved by delay loading.
-They have to be resolved indirectly via their addresses in the .map file.
-All of them are external variables. */
-extern	CHARSET_INFO*		wdl_my_charset_bin;
-extern	CHARSET_INFO*		wdl_my_charset_latin1;
-extern	CHARSET_INFO*		wdl_my_charset_filename;
-extern	CHARSET_INFO**		wdl_system_charset_info;
-extern	CHARSET_INFO**		wdl_default_charset_info;
-extern	CHARSET_INFO**		wdl_all_charsets;
-extern	system_variables*	wdl_global_system_variables;
-extern	char*			wdl_mysql_real_data_home;
-extern	char**			wdl_mysql_data_home;
-extern	char**			wdl_tx_isolation_names;
-extern	char**			wdl_binlog_format_names;
-extern	char*			wdl_reg_ext;
-extern	pthread_mutex_t*	wdl_LOCK_thread_count;
-extern	key_map*		wdl_key_map_full;
-extern	MY_TMPDIR*		wdl_mysql_tmpdir_list;
-extern	bool*			wdl_mysqld_embedded;
-extern	uint*			wdl_lower_case_table_names;
-extern	ulong*			wdl_specialflag;
-extern	int*			wdl_my_umask;
-extern	bool*			wdl_opt_bin_log;
-
-#define my_charset_bin		(*wdl_my_charset_bin)
-#define my_charset_latin1	(*wdl_my_charset_latin1)
-#define my_charset_filename	(*wdl_my_charset_filename)
-#define system_charset_info	(*wdl_system_charset_info)
-#define default_charset_info	(*wdl_default_charset_info)
-#define all_charsets		(wdl_all_charsets)
-#define global_system_variables	(*wdl_global_system_variables)
-#define mysql_real_data_home	(wdl_mysql_real_data_home)
-#define mysql_data_home		(*wdl_mysql_data_home)
-#define tx_isolation_names	(*wdl_tx_isolation_names)
-#define binlog_format_names	(*wdl_binlog_format_names)
-#define reg_ext			(wdl_reg_ext)
-#define LOCK_thread_count	(*wdl_LOCK_thread_count)
-#define key_map_full		(*wdl_key_map_full)
-#define mysql_tmpdir_list	(*wdl_mysql_tmpdir_list)
-#define mysqld_embedded		(*wdl_mysqld_embedded)
-#define lower_case_table_names	(*wdl_lower_case_table_names)
-#define specialflag		(*wdl_specialflag)
-#define my_umask		(*wdl_my_umask)
-#define opt_bin_log		(*wdl_opt_bin_log)
-
-#endif
+/***********************************************************************
+This file contains accessor functions for dynamic plugin on Windows.
+
+(c) 2008 Innobase Oy
+***********************************************************************/
+#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
+/***********************************************************************
+This is a list of externals that can not be resolved by delay loading.
+They have to be resolved indirectly via their addresses in the .map file.
+All of them are external variables. */
+extern	CHARSET_INFO*		wdl_my_charset_bin;
+extern	CHARSET_INFO*		wdl_my_charset_latin1;
+extern	CHARSET_INFO*		wdl_my_charset_filename;
+extern	CHARSET_INFO**		wdl_system_charset_info;
+extern	CHARSET_INFO**		wdl_default_charset_info;
+extern	CHARSET_INFO**		wdl_all_charsets;
+extern	system_variables*	wdl_global_system_variables;
+extern	char*			wdl_mysql_real_data_home;
+extern	char**			wdl_mysql_data_home;
+extern	char**			wdl_tx_isolation_names;
+extern	char**			wdl_binlog_format_names;
+extern	char*			wdl_reg_ext;
+extern	pthread_mutex_t*	wdl_LOCK_thread_count;
+extern	key_map*		wdl_key_map_full;
+extern	MY_TMPDIR*		wdl_mysql_tmpdir_list;
+extern	bool*			wdl_mysqld_embedded;
+extern	uint*			wdl_lower_case_table_names;
+extern	ulong*			wdl_specialflag;
+extern	int*			wdl_my_umask;
+extern	bool*			wdl_opt_bin_log;
+
+#define my_charset_bin		(*wdl_my_charset_bin)
+#define my_charset_latin1	(*wdl_my_charset_latin1)
+#define my_charset_filename	(*wdl_my_charset_filename)
+#define system_charset_info	(*wdl_system_charset_info)
+#define default_charset_info	(*wdl_default_charset_info)
+#define all_charsets		(wdl_all_charsets)
+#define global_system_variables	(*wdl_global_system_variables)
+#define mysql_real_data_home	(wdl_mysql_real_data_home)
+#define mysql_data_home		(*wdl_mysql_data_home)
+#define tx_isolation_names	(*wdl_tx_isolation_names)
+#define binlog_format_names	(*wdl_binlog_format_names)
+#define reg_ext			(wdl_reg_ext)
+#define LOCK_thread_count	(*wdl_LOCK_thread_count)
+#define key_map_full		(*wdl_key_map_full)
+#define mysql_tmpdir_list	(*wdl_mysql_tmpdir_list)
+#define mysqld_embedded		(*wdl_mysqld_embedded)
+#define lower_case_table_names	(*wdl_lower_case_table_names)
+#define specialflag		(*wdl_specialflag)
+#define my_umask		(*wdl_my_umask)
+#define opt_bin_log		(*wdl_opt_bin_log)
+
+#endif
diff --git a/handler/win_delay_loader.cc b/handler/win_delay_loader.cc
index 7849fe3f3d7..fc718358db8 100644
--- a/handler/win_delay_loader.cc
+++ b/handler/win_delay_loader.cc
@@ -1,1011 +1,1011 @@
-/***********************************************************************
-This file contains functions that implement the delay loader on Windows.
-
-This is a customized version of delay loader with limited functionalities.
-It does not support:
-
-* (manual) unloading
-* multiple delay loaded DLLs
-* multiple loading of the same DLL
-
-This delay loader is used only by the InnoDB plugin. Other components (DLLs)
-can still use the default delay loader, provided by MSVC.
-
-Several acronyms used by Microsoft:
- * IAT: import address table
- * INT: import name table
- * RVA: Relative Virtual Address
-
-See http://msdn.microsoft.com/en-us/magazine/bb985992.aspx for details of
-PE format.
-
-(c) 2008 Innobase Oy
-***********************************************************************/
-#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# include <delayimp.h>
-# include <mysql_priv.h>
-
-extern "C" {
-# include "univ.i"
-# include "hash0hash.h"
-}
-
-/***********************************************************************
-This following contains a list of externals that can not be resolved by
-delay loading. They have to be resolved indirectly via their addresses
-in the .map file. All of them are external variables. */
-CHARSET_INFO*		wdl_my_charset_bin;
-CHARSET_INFO*		wdl_my_charset_latin1;
-CHARSET_INFO*		wdl_my_charset_filename;
-CHARSET_INFO**		wdl_system_charset_info;
-CHARSET_INFO**		wdl_default_charset_info;
-CHARSET_INFO**		wdl_all_charsets;
-system_variables*	wdl_global_system_variables;
-char*			wdl_mysql_real_data_home;
-char**			wdl_mysql_data_home;
-char**			wdl_tx_isolation_names;
-char**			wdl_binlog_format_names;
-char*			wdl_reg_ext;
-pthread_mutex_t*	wdl_LOCK_thread_count;
-key_map*		wdl_key_map_full;
-MY_TMPDIR*		wdl_mysql_tmpdir_list;
-bool*			wdl_mysqld_embedded;
-uint*			wdl_lower_case_table_names;
-ulong*			wdl_specialflag;
-int*			wdl_my_umask;
-bool*			wdl_opt_bin_log;
-
-/***********************************************************************
-The following is defined in ha_innodb.cc. It is used for copying the
-system variables from the builtin innodb plugin to the dynamic plugin.
-*/
-extern struct st_mysql_plugin*	builtin_innobase_plugin_ptr;
-
-/***********************************************************************
-The preffered load-address defined in PE (portable executable format).*/
-#if defined(_M_IA64)
-#pragma section(".base", long, read)
-extern "C"
-__declspec(allocate(".base"))
-const IMAGE_DOS_HEADER __ImageBase;
-#else
-extern "C"
-const IMAGE_DOS_HEADER __ImageBase;
-#endif
-
-/***********************************************************************
-A template function for converting a relative address (RVA) to an
-absolute address (VA). This is due to the pointers in the delay
-descriptor (ImgDelayDescr in delayimp.h) have been changed from
-VAs to RVAs to work on both 32- and 64-bit platforms. */
-template <class X>
-X PFromRva(RVA rva) {
-	return X(PBYTE(&__ImageBase) + rva);
-}
-
-/***********************************************************************
-Convert to the old format for convenience. The structure as well as its
-element names follow the definition of ImgDelayDescr in delayimp.h. */
-struct InternalImgDelayDescr {
-	DWORD		grAttrs;	/* attributes */
-	LPCSTR		szName;		/* pointer to dll name */
-	HMODULE*	phmod;		/* address of module handle */
-	PImgThunkData	pIAT;		/* address of the IAT */
-	PCImgThunkData	pINT;		/* address of the INT */
-	PCImgThunkData	pBoundIAT;	/* address of the optional bound IAT */
-	PCImgThunkData	pUnloadIAT;	/* address of optional copy of
-					   original IAT */
-	DWORD		dwTimeStamp;	/* 0 if not bound,
-					   otherwise date/time stamp of DLL
-					   bound to (Old BIND) */
-};
-
-typedef struct map_hash_chain_struct	map_hash_chain_t;
-
-struct map_hash_chain_struct {
-	char*			symbol;	/* pointer to a symbol */
-	ulint			value;	/* address of the symbol */
-	map_hash_chain_t*	next;	/* pointer to the next cell
-					in the same folder. */
-	map_hash_chain_t*	chain;	/* a linear chain used for
-					cleanup. */
-};
-
-static HMODULE				my_hmod = 0;
-static struct hash_table_struct*	m_htbl = NULL ;
-static map_hash_chain_t*		chain_header = NULL;
-static ibool				wdl_init = FALSE;
-const ulint				MAP_HASH_CELLS_NUM = 10000;
-
-#ifndef DBUG_OFF
-/***********************************************************************
-In the dynamic plugin, it is required to call the following dbug functions
-in the server:
-	_db_pargs_
-	_db_doprnt_
-	_db_enter_
-	_db_return_
-	_db_dump_
-
-The plugin will get those function pointers during the initialization.
-*/
-typedef void (__cdecl* pfn_db_enter_)(
-	const char*	_func_,
-	const char*	_file_,
-	uint		_line_,
-	const char**	_sfunc_,
-	const char**	_sfile_,
-	uint*		_slevel_,
-	char***);
-
-typedef void (__cdecl* pfn_db_return_)(
-	uint		_line_,
-	const char**	_sfunc_,
-	const char**	_sfile_,
-	uint*		_slevel_);
-
-typedef void (__cdecl* pfn_db_pargs_)(
-	uint		_line_,
-	const char*	keyword);
-
-typedef void (__cdecl* pfn_db_doprnt_)(
-	const char*	format,
-	...);
-
-typedef void (__cdecl* pfn_db_dump_)(
-	uint			_line_,
-	const char*		keyword,
-	const unsigned char*	memory,
-	size_t			length);
-
-static pfn_db_enter_	wdl_db_enter_;
-static pfn_db_return_	wdl_db_return_;
-static pfn_db_pargs_	wdl_db_pargs_;
-static pfn_db_doprnt_	wdl_db_doprnt_;
-static pfn_db_dump_	wdl_db_dump_;
-#endif /* !DBUG_OFF */
-
-/*****************************************************************
-Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n.
-
-This is the same function as hash_create in hash0hash.c, except the
-memory allocation. This function is invoked before the engine is
-initialized, and buffer pools are not ready yet. */
-static
-hash_table_t*
-wdl_hash_create(
-/*============*/
-			/* out, own: created hash table */
-	ulint	n)	/* in: number of array cells */
-{
-	hash_cell_t*	array;
-	ulint		prime;
-	hash_table_t*	table;
-
-	prime = ut_find_prime(n);
-
-	table = (hash_table_t*) malloc(sizeof(hash_table_t));
-	if (table == NULL) {
-		return(NULL);
-	}
-
-	array = (hash_cell_t*) malloc(sizeof(hash_cell_t) * prime);
-	if (array == NULL) {
-		free(table);
-		return(NULL);
-	}
-
-	table->array = array;
-	table->n_cells = prime;
-	table->n_mutexes = 0;
-	table->mutexes = NULL;
-	table->heaps = NULL;
-	table->heap = NULL;
-	table->magic_n = HASH_TABLE_MAGIC_N;
-
-	/* Initialize the cell array */
-	hash_table_clear(table);
-
-	return(table);
-}
-
-/*****************************************************************
-Frees a hash table. */
-static
-void
-wdl_hash_table_free(
-/*================*/
-	hash_table_t*	table)	/* in, own: hash table */
-{
-	ut_a(table != NULL);
-	ut_a(table->mutexes == NULL);
-
-	free(table->array);
-	free(table);
-}
-
-/***********************************************************************
-Function for calculating the count of imports given the base of the IAT. */
-static
-ulint
-wdl_import_count(
-/*=============*/
-					/* out: number of imports */
-	PCImgThunkData	pitd_base)	/* in: base of the IAT */
-{
-	ulint		ret = 0;
-	PCImgThunkData	pitd = pitd_base;
-
-	while (pitd->u1.Function) {
-		pitd++;
-		ret++;
-	}
-
-	return(ret);
-}
-
-/***********************************************************************
-Read Mapfile to a hashtable for faster access */
-static
-ibool
-wdl_load_mapfile(
-/*=============*/
-					/* out: TRUE if the mapfile is
-					loaded successfully. */
-	const char*	filename)	/* in: name of the mapfile. */
-{
-	FILE*		fp;
-	const size_t	nSize = 256;
-	char		tmp_buf[nSize];
-	char*		func_name;
-	char*		func_addr;
-	ulint		load_addr = 0;
-	ibool		valid_load_addr = FALSE;
-
-	fp = fopen(filename, "r");
-	if (fp == NULL) {
-
-		return(FALSE);
-	}
-
-	/* Check whether to create the hashtable */
-	if (m_htbl == NULL) {
-
-		m_htbl = wdl_hash_create(MAP_HASH_CELLS_NUM);
-
-		if (m_htbl == NULL) {
-
-			fclose(fp);
-			return(FALSE);
-		}
-	}
-
-	/* Search start of symbol list and get the preferred load address */
-	while (fgets(tmp_buf, sizeof(tmp_buf), fp)) {
-
-		if (sscanf(tmp_buf, " Preferred load address is %16X",
-			   &load_addr) == 1) {
-
-			valid_load_addr = TRUE;
-		}
-
-		if (strstr(tmp_buf, "Rva+Base") != NULL) {
-
-			break;
-		}
-	}
-
-	if (valid_load_addr == FALSE) {
-
-		/* No "Preferred load address", the map file is wrong. */
-		fclose(fp);
-		return(FALSE);
-	}
-
-	/* Read symbol list */
-	while (fgets(tmp_buf, sizeof(tmp_buf), fp))
-	{
-		map_hash_chain_t*	map_cell;
-		ulint			map_fold;
-
-		if (*tmp_buf == 0) {
-
-			continue;
-		}
-
-		func_name = strtok(tmp_buf, " ");
-		func_name = strtok(NULL, " ");
-		func_addr = strtok(NULL, " ");
-
-		if (func_name && func_addr) {
-
-			ut_snprintf(tmp_buf, nSize, "0x%s", func_addr);
-			if (*func_name == '_') {
-
-				func_name++;
-			}
-
-			map_cell = (map_hash_chain_t*)
-				   malloc(sizeof(map_hash_chain_t));
-			if (map_cell == NULL) {
-				return(FALSE);
-			}
-
-			/* Chain all cells together */
-			map_cell->chain = chain_header;
-			chain_header = map_cell;
-
-			map_cell->symbol = strdup(func_name);
-			map_cell->value = strtoul(tmp_buf, NULL, 0)
-					  - load_addr;
-			map_fold = ut_fold_string(map_cell->symbol);
-
-			HASH_INSERT(map_hash_chain_t,
-				    next,
-				    m_htbl,
-				    map_fold,
-				    map_cell);
-		}
-	}
-
-	fclose(fp);
-
-	return(TRUE);
-}
-
-/*****************************************************************
-Cleanup.during DLL unload */
-static
-void
-wdl_cleanup(void)
-/*=============*/
-{
-	while (chain_header != NULL) {
-		map_hash_chain_t*	tmp;
-
-		tmp = chain_header->chain;
-		free(chain_header->symbol);
-		free(chain_header);
-		chain_header = tmp;
-	}
-
-	if (m_htbl != NULL) {
-
-		wdl_hash_table_free(m_htbl);
-	}
-}
-
-/***********************************************************************
-Load the mapfile mysqld.map. */
-static
-HMODULE
-wdl_get_mysqld_mapfile(void)
-/*========================*/
-			/* out: the module handle */
-{
-	char	file_name[MAX_PATH];
-	char*	ext;
-	ulint	err;
-
-	if (my_hmod == 0) {
-
-		size_t	nSize = MAX_PATH - strlen(".map") -1;
-
-		/* First find out the name of current executable */
-		my_hmod = GetModuleHandle(NULL);
-		if (my_hmod == 0) {
-
-			return(my_hmod);
-		}
-
-		err = GetModuleFileName(my_hmod, file_name, nSize);
-		if (err == 0) {
-
-			my_hmod = 0;
-			return(my_hmod);
-		}
-
-		ext = strrchr(file_name, '.');
-		if (ext != NULL) {
-
-			*ext = 0;
-			strcat(file_name, ".map");
-
-			err = wdl_load_mapfile(file_name);
-			if (err == 0) {
-
-				my_hmod = 0;
-			}
-		} else {
-
-			my_hmod = 0;
-		}
-	}
-
-	return(my_hmod);
-}
-
-/***********************************************************************
-Retrieves the address of an exported function. It follows the convention
-of GetProcAddress(). */
-static
-FARPROC
-wdl_get_procaddr_from_map(
-/*======================*/
-					/* out: address of exported
-					function. */
-	HANDLE		m_handle,	/* in: module handle */
-	const char*	import_proc)	/* in: procedure name */
-{
-	map_hash_chain_t*	hash_chain;
-	ulint			map_fold;
-
-	map_fold = ut_fold_string(import_proc);
-	HASH_SEARCH(
-		next,
-		m_htbl,
-		map_fold,
-		map_hash_chain_t*,
-		hash_chain,
-		(ut_strcmp(hash_chain->symbol, import_proc) == 0));
-
-	if (hash_chain == NULL) {
-
-#ifdef _WIN64
-		/* On Win64, the leading '_' may not be taken out. In this
-		case, search again without the leading '_'. */
-		if (*import_proc == '_') {
-
-			import_proc++;
-		}
-
-		map_fold = ut_fold_string(import_proc);
-		HASH_SEARCH(
-			next,
-			m_htbl,
-			map_fold,
-			map_hash_chain_t*,
-			hash_chain,
-			(ut_strcmp(hash_chain->symbol, import_proc) == 0));
-
-		if (hash_chain == NULL) {
-#endif
-			if (wdl_init == TRUE) {
-
-				sql_print_error(
-					"InnoDB: the procedure pointer of %s"
-					" is not found.",
-					import_proc);
-			}
-
-			return(0);
-#ifdef _WIN64
-		}
-#endif
-	}
-
-	return((FARPROC) ((ulint) m_handle + hash_chain->value));
-}
-
-/***********************************************************************
-Retrieves the address of an exported variable.
-Note: It does not follow the Windows call convention FARPROC. */
-static
-void*
-wdl_get_varaddr_from_map(
-/*=====================*/
-						/* out: address of exported
-						variable. */
-	HANDLE		m_handle,		/* in: module handle */
-	const char*	import_variable)	/* in: variable name */
-{
-	map_hash_chain_t*	hash_chain;
-	ulint			map_fold;
-
-	map_fold = ut_fold_string(import_variable);
-	HASH_SEARCH(
-		next,
-		m_htbl,
-		map_fold,
-		map_hash_chain_t*,
-		hash_chain,
-		(ut_strcmp(hash_chain->symbol, import_variable) == 0));
-
-	if (hash_chain == NULL) {
-
-#ifdef _WIN64
-		/* On Win64, the leading '_' may not be taken out. In this
-		case, search again without the leading '_'. */
-		if (*import_variable == '_') {
-
-			import_variable++;
-		}
-
-		map_fold = ut_fold_string(import_variable);
-		HASH_SEARCH(
-			next,
-			m_htbl,
-			map_fold,
-			map_hash_chain_t*,
-			hash_chain,
-			(ut_strcmp(hash_chain->symbol, import_variable) == 0));
-
-		if (hash_chain == NULL) {
-#endif
-			if (wdl_init == TRUE) {
-
-				sql_print_error(
-					"InnoDB: the variable address of %s"
-					" is not found.",
-					import_variable);
-			}
-
-			return(0);
-#ifdef _WIN64
-		}
-#endif
-	}
-
-	return((void*) ((ulint) m_handle + hash_chain->value));
-}
-
-/***********************************************************************
-Bind all unresolved external variables from the MySQL executable. */
-static
-bool
-wdl_get_external_variables(void)
-/*============================*/
-			/* out: TRUE if successful */
-{
-	HMODULE	hmod = wdl_get_mysqld_mapfile();
-
-	if (hmod == 0) {
-
-		return(FALSE);
-	}
-
-#define GET_SYM(sym, var, type)					\
-	var = (type*) wdl_get_varaddr_from_map(hmod, sym);	\
-	if (var == NULL) return(FALSE)
-#ifdef _WIN64
-#define GET_SYM2(sym1, sym2, var, type)				\
-	var = (type*) wdl_get_varaddr_from_map(hmod, sym1);	\
-	if (var == NULL) return(FALSE)
-#else
-#define GET_SYM2(sym1, sym2, var, type)				\
-	var = (type*) wdl_get_varaddr_from_map(hmod, sym2);	\
-	if (var == NULL) return(FALSE)
-#endif // (_WIN64)
-#define GET_C_SYM(sym, type) GET_SYM(#sym, wdl_##sym, type)
-#define GET_PROC_ADDR(sym)					\
-	wdl##sym = (pfn##sym) wdl_get_procaddr_from_map(hmod, #sym)
-
-	GET_C_SYM(my_charset_bin, CHARSET_INFO);
-	GET_C_SYM(my_charset_latin1, CHARSET_INFO);
-	GET_C_SYM(my_charset_filename, CHARSET_INFO);
-	GET_C_SYM(default_charset_info, CHARSET_INFO*);
-	GET_C_SYM(all_charsets, CHARSET_INFO*);
-	GET_C_SYM(my_umask, int);
-
-	GET_SYM("?global_system_variables@@3Usystem_variables@@A",
-		wdl_global_system_variables, struct system_variables);
-	GET_SYM("?mysql_real_data_home@@3PADA",
-		wdl_mysql_real_data_home, char);
-	GET_SYM("?reg_ext@@3PADA", wdl_reg_ext, char);
-	GET_SYM("?LOCK_thread_count@@3U_RTL_CRITICAL_SECTION@@A",
-		wdl_LOCK_thread_count, pthread_mutex_t);
-	GET_SYM("?key_map_full@@3V?$Bitmap@$0EA@@@A",
-		wdl_key_map_full, key_map);
-	GET_SYM("?mysql_tmpdir_list@@3Ust_my_tmpdir@@A",
-		wdl_mysql_tmpdir_list, MY_TMPDIR);
-	GET_SYM("?mysqld_embedded@@3_NA",
-		wdl_mysqld_embedded, bool);
-	GET_SYM("?lower_case_table_names@@3IA",
-		wdl_lower_case_table_names, uint);
-	GET_SYM("?specialflag@@3KA", wdl_specialflag, ulong);
-	GET_SYM("?builtin_innobase_plugin@@3PAUst_mysql_plugin@@A",
-		builtin_innobase_plugin_ptr, struct st_mysql_plugin);
-	GET_SYM("?opt_bin_log@@3_NA",
-		wdl_opt_bin_log, bool);
-
-	GET_SYM2("?system_charset_info@@3PEAUcharset_info_st@@EA",
-		 "?system_charset_info@@3PAUcharset_info_st@@A",
-		 wdl_system_charset_info, CHARSET_INFO*);
-	GET_SYM2("?mysql_data_home@@3PEADEA",
-		 "?mysql_data_home@@3PADA",
-		 wdl_mysql_data_home, char*);
-	GET_SYM2("?tx_isolation_names@@3PAPEBDA",
-		 "?tx_isolation_names@@3PAPBDA",
-		 wdl_tx_isolation_names, char*);
-	GET_SYM2("?binlog_format_names@@3PAPEBDA",
-		 "?binlog_format_names@@3PAPBDA",
-		 wdl_binlog_format_names, char*);
-
-#ifndef DBUG_OFF
-	GET_PROC_ADDR(_db_enter_);
-	GET_PROC_ADDR(_db_return_);
-	GET_PROC_ADDR(_db_pargs_);
-	GET_PROC_ADDR(_db_doprnt_);
-	GET_PROC_ADDR(_db_dump_);
-
-	/* If any of the dbug functions is not available, just make them
-	all invalid. This is the case when working with a non-debug
-	version of the server. */
-	if (wdl_db_enter_ == NULL || wdl_db_return_ == NULL
-	    || wdl_db_pargs_ == NULL || wdl_db_doprnt_ == NULL
-	    || wdl_db_dump_ == NULL) {
-
-		wdl_db_enter_ = NULL;
-		wdl_db_return_ = NULL;
-		wdl_db_pargs_ = NULL;
-		wdl_db_doprnt_ = NULL;
-		wdl_db_dump_ = NULL;
-	}
-#endif /* !DBUG_OFF */
-
-	wdl_init = TRUE;
-	return(TRUE);
-
-#undef GET_SYM
-#undef GET_SYM2
-#undef GET_C_SYM
-#undef GET_PROC_ADDR
-}
-
-/***********************************************************************
-The DLL Delayed Loading Helper Function for resolving externals.
-
-The function may fail due to one of the three reasons:
-
-* Invalid parameter, which happens if the attributes in pidd aren't
-  specified correctly.
-* Failed to load the map file mysqld.map.
-* Failed to find an external name in the map file mysqld.map.
-
-Note: this function is called by run-time as well as __HrLoadAllImportsForDll.
-So, it has to follow Windows call convention. */
-extern "C"
-FARPROC WINAPI
-__delayLoadHelper2(
-/*===============*/
-					/* out: the address of the imported
-					function*/
-	PCImgDelayDescr	pidd,		/* in: a const pointer to a
-					ImgDelayDescr, see delayimp.h. */
-	FARPROC*	iat_entry)	/* in/out: A pointer to the slot in
-					the delay load import address table
-					to be updated with the address of the
-					imported function. */
-{
-	ulint		iIAT, iINT;
-	HMODULE		hmod;
-	PCImgThunkData	pitd;
-	FARPROC		fun = NULL;
-
-	/* Set up data used for the hook procs  */
-	InternalImgDelayDescr	idd = {
-				pidd->grAttrs,
-				PFromRva<LPCSTR>(pidd->rvaDLLName),
-				PFromRva<HMODULE*>(pidd->rvaHmod),
-				PFromRva<PImgThunkData>(pidd->rvaIAT),
-				PFromRva<PCImgThunkData>(pidd->rvaINT),
-				PFromRva<PCImgThunkData>(pidd->rvaBoundIAT),
-				PFromRva<PCImgThunkData>(pidd->rvaUnloadIAT),
-				pidd->dwTimeStamp
-	};
-
-	DelayLoadInfo		dli = {
-				sizeof(DelayLoadInfo),
-				pidd,
-				iat_entry,
-				idd.szName,
-				{0},
-				0,
-				0,
-				0
-	};
-
-	/* Check the Delay Load Attributes, log an error of invalid
-	parameter, which happens if the attributes in pidd are not
-	specified correctly. */
-	if ((idd.grAttrs & dlattrRva) == 0) {
-
-		sql_print_error("InnoDB: invalid parameter for delay loader.");
-		return(0);
-	}
-
-	hmod = *idd.phmod;
-
-	/* Calculate the index for the IAT entry in the import address table.
-	The INT entries are ordered the same as the IAT entries so the
-	calculation can be done on the IAT side. */
-	iIAT = (PCImgThunkData) iat_entry - idd.pIAT;
-	iINT = iIAT;
-
-	pitd = &(idd.pINT[iINT]);
-
-	dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pitd->u1.Ordinal);
-
-	if (dli.dlp.fImportByName) {
-
-		dli.dlp.szProcName = (LPCSTR) (PFromRva<PIMAGE_IMPORT_BY_NAME>
-			((RVA) ((UINT_PTR) pitd->u1.AddressOfData))->Name);
-	} else {
-
-		dli.dlp.dwOrdinal = (ulint) IMAGE_ORDINAL(pitd->u1.Ordinal);
-	}
-
-	/* Now, load the mapfile, if it has not been done yet */
-	if (hmod == 0) {
-
-		hmod = wdl_get_mysqld_mapfile();
-	}
-
-	if (hmod == 0) {
-		/* LoadLibrary failed. */
-		PDelayLoadInfo	rgpdli[1] = {&dli};
-
-		dli.dwLastError = ::GetLastError();
-
-		sql_print_error(
-			"InnoDB: failed to load mysqld.map with error %d.",
-			dli.dwLastError);
-
-		return(0);
-	}
-
-	/* Store the library handle. */
-	idd.phmod = &hmod;
-
-	/* Go for the procedure now. */
-	dli.hmodCur = hmod;
-
-	if (pidd->rvaBoundIAT && pidd->dwTimeStamp) {
-
-		/* Bound imports exist, check the timestamp from the target
-		image */
-		PIMAGE_NT_HEADERS	pinh;
-
-		pinh = (PIMAGE_NT_HEADERS) ((byte*) hmod
-				+ ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
-
-		if (pinh->Signature == IMAGE_NT_SIGNATURE
-		    && pinh->FileHeader.TimeDateStamp == idd.dwTimeStamp
-		    && (DWORD) hmod == pinh->OptionalHeader.ImageBase) {
-
-			/* We have a decent address in the bound IAT. */
-			fun = (FARPROC) (UINT_PTR)
-					idd.pBoundIAT[iIAT].u1.Function;
-
-			if (fun) {
-
-				*iat_entry = fun;
-				return(fun);
-			}
-		}
-	}
-
-	fun = wdl_get_procaddr_from_map(hmod, dli.dlp.szProcName);
-
-	if (fun == 0) {
-
-		return(0);
-	}
-
-	*iat_entry = fun;
-	return(fun);
-}
-
-/***********************************************************************
-Unload a DLL that was delay loaded. This function is called by run-time. */
-extern "C"
-BOOL WINAPI
-__FUnloadDelayLoadedDLL2(
-/*=====================*/
-				/* out: TRUE is returned if the DLL is found
-				and the IAT matches the original one. */
-	LPCSTR	module_name)	/* in: DLL name */
-{
-	return(TRUE);
-}
-
-/******************************************************************
-Load all imports from a DLL that was specified with the /delayload linker
-option.
-Note: this function is called by run-time. So, it has to follow Windows call
-convention. */
-extern "C"
-HRESULT WINAPI
-__HrLoadAllImportsForDll(
-/*=====================*/
-				/* out: S_OK if the DLL matches, otherwise
-				ERROR_MOD_NOT_FOUND is returned. */
-	LPCSTR	module_name)	/* in: DLL name */
-{
-	PIMAGE_NT_HEADERS	img;
-	PCImgDelayDescr		pidd;
-	IMAGE_DATA_DIRECTORY*	image_data;
-	LPCSTR			current_module;
-	HRESULT			ret = ERROR_MOD_NOT_FOUND;
-	HMODULE			hmod = (HMODULE) &__ImageBase;
-
-	img = (PIMAGE_NT_HEADERS) ((byte*) hmod
-				   + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
-	image_data =
-	 &img->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
-
-	/* Scan the delay load IAT/INT for the DLL */
-	if (image_data->Size) {
-
-		pidd = PFromRva<PCImgDelayDescr>(image_data->VirtualAddress);
-
-		/* Check all of the listed DLLs we want to load. */
-		while (pidd->rvaDLLName) {
-
-			current_module = PFromRva<LPCSTR>(pidd->rvaDLLName);
-
-			if (stricmp(module_name, current_module) == 0) {
-
-				/* Found it, break out with pidd and
-				current_module set appropriately */
-				break;
-			}
-
-			/* To the next delay import descriptor */
-			pidd++;
-		}
-
-		if (pidd->rvaDLLName) {
-
-			/* Found a matching DLL, now process it. */
-			FARPROC*	iat_entry;
-			size_t		count;
-
-			iat_entry = PFromRva<FARPROC*>(pidd->rvaIAT);
-			count = wdl_import_count((PCImgThunkData) iat_entry);
-
-			/* now load all the imports from the DLL */
-			while (count > 0) {
-
-				/* No need to check the return value */
-				__delayLoadHelper2(pidd, iat_entry);
-				iat_entry++;
-				count--;
-			}
-
-			ret = S_OK;
-		}
-	}
-
-	return ret;
-}
-
-/******************************************************************
-The main function of a DLL */
-BOOL
-WINAPI
-DllMain(
-/*====*/
-					/* out: TRUE if the call succeeds */
-	HINSTANCE	hinstDLL,	/* in: handle to the DLL module */
-	DWORD		fdwReason,	/* Reason code that indicates why the
-					DLL entry-point function is being
-					called.*/
-	LPVOID		lpvReserved)	/* in: additional parameter based on
-					fdwReason */
-{
-	BOOL	success = TRUE;
-
-	switch (fdwReason) {
-
-	case DLL_PROCESS_ATTACH:
-		success = wdl_get_external_variables();
-		break;
-
-	case DLL_PROCESS_DETACH:
-		wdl_cleanup();
-		break;
-	}
-
-	return(success);
-}
-
-#ifndef DBUG_OFF
-/******************************************************************
-Process entry point to user function. It makes the call to _db_enter_
-in mysqld.exe. The DBUG functions are defined in my_dbug.h. */
-extern "C" UNIV_INTERN
-void
-_db_enter_(
-	const char*	_func_,		/* in: current function name */
-	const char*	_file_,		/* in: current file name */
-	uint		_line_,		/* in: current source line number */
-	const char**	_sfunc_,	/* out: previous _func_ */
-	const char**	_sfile_,	/* out: previous _file_ */
-	uint*		_slevel_,	/* out: previous nesting level */
-	char***		_sframep_)	/* out: previous frame pointer */
-{
-	if (wdl_db_enter_ != NULL) {
-
-		wdl_db_enter_(_func_, _file_, _line_, _sfunc_, _sfile_,
-			      _slevel_, _sframep_);
-	}
-}
-
-/******************************************************************
-Process exit from user function. It makes the call to _db_return_()
-in the server. */
-extern "C" UNIV_INTERN
-void
-_db_return_(
-	uint		_line_,		/* in: current source line number */
-	const char**	_sfunc_,	/* out: previous _func_ */
-	const char**	_sfile_,	/* out: previous _file_ */
-	uint*		_slevel_)	/* out: previous level */
-{
-	if (wdl_db_return_ != NULL) {
-
-		wdl_db_return_(_line_, _sfunc_, _sfile_, _slevel_);
-	}
-}
-
-/******************************************************************
-Log arguments for subsequent use. It makes the call to _db_pargs_()
-in the server. */
-extern "C" UNIV_INTERN
-void
-_db_pargs_(
-	uint		_line_,		/* in: current source line number */
-	const char*	keyword)	/* in: keyword for current macro */
-{
-	if (wdl_db_pargs_ != NULL) {
-
-		wdl_db_pargs_(_line_, keyword);
-	}
-}
-
-/******************************************************************
-Handle print of debug lines. It saves the text into a buffer first,
-then makes the call to _db_doprnt_() in the server. The text is
-truncated to the size of buffer. */
-extern "C" UNIV_INTERN
-void
-_db_doprnt_(
-	const char*	format,		/* in: the format string */
-	...)				/* in: list of arguments */
-{
-	va_list		argp;
-	char		buffer[512];
-
-	if (wdl_db_doprnt_ != NULL) {
-
-		va_start(argp, format);
-		/* it is ok to ignore the trunction. */
-		_vsnprintf(buffer, sizeof(buffer), format, argp);
-		wdl_db_doprnt_(buffer);
-		va_end(argp);
-	}
-}
-
-/******************************************************************
-Dump a string in hex. It makes the call to _db_dump_() in the server. */
-extern "C" UNIV_INTERN
-void
-_db_dump_(
-	uint			_line_,		/* in: current source line
-						number */
-	const char*		keyword,	/* in: keyword list */
-	const unsigned char*	memory,		/* in: memory to dump */
-	size_t			length)		/* in: bytes to dump */
-{
-	if (wdl_db_dump_ != NULL) {
-
-		wdl_db_dump_(_line_, keyword, memory, length);
-	}
-}
-
-#endif /* !DBUG_OFF */
-#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
+/***********************************************************************
+This file contains functions that implement the delay loader on Windows.
+
+This is a customized version of delay loader with limited functionalities.
+It does not support:
+
+* (manual) unloading
+* multiple delay loaded DLLs
+* multiple loading of the same DLL
+
+This delay loader is used only by the InnoDB plugin. Other components (DLLs)
+can still use the default delay loader, provided by MSVC.
+
+Several acronyms used by Microsoft:
+ * IAT: import address table
+ * INT: import name table
+ * RVA: Relative Virtual Address
+
+See http://msdn.microsoft.com/en-us/magazine/bb985992.aspx for details of
+PE format.
+
+(c) 2008 Innobase Oy
+***********************************************************************/
+#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <delayimp.h>
+# include <mysql_priv.h>
+
+extern "C" {
+# include "univ.i"
+# include "hash0hash.h"
+}
+
+/***********************************************************************
+This following contains a list of externals that can not be resolved by
+delay loading. They have to be resolved indirectly via their addresses
+in the .map file. All of them are external variables. */
+CHARSET_INFO*		wdl_my_charset_bin;
+CHARSET_INFO*		wdl_my_charset_latin1;
+CHARSET_INFO*		wdl_my_charset_filename;
+CHARSET_INFO**		wdl_system_charset_info;
+CHARSET_INFO**		wdl_default_charset_info;
+CHARSET_INFO**		wdl_all_charsets;
+system_variables*	wdl_global_system_variables;
+char*			wdl_mysql_real_data_home;
+char**			wdl_mysql_data_home;
+char**			wdl_tx_isolation_names;
+char**			wdl_binlog_format_names;
+char*			wdl_reg_ext;
+pthread_mutex_t*	wdl_LOCK_thread_count;
+key_map*		wdl_key_map_full;
+MY_TMPDIR*		wdl_mysql_tmpdir_list;
+bool*			wdl_mysqld_embedded;
+uint*			wdl_lower_case_table_names;
+ulong*			wdl_specialflag;
+int*			wdl_my_umask;
+bool*			wdl_opt_bin_log;
+
+/***********************************************************************
+The following is defined in ha_innodb.cc. It is used for copying the
+system variables from the builtin innodb plugin to the dynamic plugin.
+*/
+extern struct st_mysql_plugin*	builtin_innobase_plugin_ptr;
+
+/***********************************************************************
+The preffered load-address defined in PE (portable executable format).*/
+#if defined(_M_IA64)
+#pragma section(".base", long, read)
+extern "C"
+__declspec(allocate(".base"))
+const IMAGE_DOS_HEADER __ImageBase;
+#else
+extern "C"
+const IMAGE_DOS_HEADER __ImageBase;
+#endif
+
+/***********************************************************************
+A template function for converting a relative address (RVA) to an
+absolute address (VA). This is due to the pointers in the delay
+descriptor (ImgDelayDescr in delayimp.h) have been changed from
+VAs to RVAs to work on both 32- and 64-bit platforms. */
+template <class X>
+X PFromRva(RVA rva) {
+	return X(PBYTE(&__ImageBase) + rva);
+}
+
+/***********************************************************************
+Convert to the old format for convenience. The structure as well as its
+element names follow the definition of ImgDelayDescr in delayimp.h. */
+struct InternalImgDelayDescr {
+	DWORD		grAttrs;	/* attributes */
+	LPCSTR		szName;		/* pointer to dll name */
+	HMODULE*	phmod;		/* address of module handle */
+	PImgThunkData	pIAT;		/* address of the IAT */
+	PCImgThunkData	pINT;		/* address of the INT */
+	PCImgThunkData	pBoundIAT;	/* address of the optional bound IAT */
+	PCImgThunkData	pUnloadIAT;	/* address of optional copy of
+					   original IAT */
+	DWORD		dwTimeStamp;	/* 0 if not bound,
+					   otherwise date/time stamp of DLL
+					   bound to (Old BIND) */
+};
+
+typedef struct map_hash_chain_struct	map_hash_chain_t;
+
+struct map_hash_chain_struct {
+	char*			symbol;	/* pointer to a symbol */
+	ulint			value;	/* address of the symbol */
+	map_hash_chain_t*	next;	/* pointer to the next cell
+					in the same folder. */
+	map_hash_chain_t*	chain;	/* a linear chain used for
+					cleanup. */
+};
+
+static HMODULE				my_hmod = 0;
+static struct hash_table_struct*	m_htbl = NULL ;
+static map_hash_chain_t*		chain_header = NULL;
+static ibool				wdl_init = FALSE;
+const ulint				MAP_HASH_CELLS_NUM = 10000;
+
+#ifndef DBUG_OFF
+/***********************************************************************
+In the dynamic plugin, it is required to call the following dbug functions
+in the server:
+	_db_pargs_
+	_db_doprnt_
+	_db_enter_
+	_db_return_
+	_db_dump_
+
+The plugin will get those function pointers during the initialization.
+*/
+typedef void (__cdecl* pfn_db_enter_)(
+	const char*	_func_,
+	const char*	_file_,
+	uint		_line_,
+	const char**	_sfunc_,
+	const char**	_sfile_,
+	uint*		_slevel_,
+	char***);
+
+typedef void (__cdecl* pfn_db_return_)(
+	uint		_line_,
+	const char**	_sfunc_,
+	const char**	_sfile_,
+	uint*		_slevel_);
+
+typedef void (__cdecl* pfn_db_pargs_)(
+	uint		_line_,
+	const char*	keyword);
+
+typedef void (__cdecl* pfn_db_doprnt_)(
+	const char*	format,
+	...);
+
+typedef void (__cdecl* pfn_db_dump_)(
+	uint			_line_,
+	const char*		keyword,
+	const unsigned char*	memory,
+	size_t			length);
+
+static pfn_db_enter_	wdl_db_enter_;
+static pfn_db_return_	wdl_db_return_;
+static pfn_db_pargs_	wdl_db_pargs_;
+static pfn_db_doprnt_	wdl_db_doprnt_;
+static pfn_db_dump_	wdl_db_dump_;
+#endif /* !DBUG_OFF */
+
+/*****************************************************************
+Creates a hash table with >= n array cells. The actual number of cells is
+chosen to be a prime number slightly bigger than n.
+
+This is the same function as hash_create in hash0hash.c, except the
+memory allocation. This function is invoked before the engine is
+initialized, and buffer pools are not ready yet. */
+static
+hash_table_t*
+wdl_hash_create(
+/*============*/
+			/* out, own: created hash table */
+	ulint	n)	/* in: number of array cells */
+{
+	hash_cell_t*	array;
+	ulint		prime;
+	hash_table_t*	table;
+
+	prime = ut_find_prime(n);
+
+	table = (hash_table_t*) malloc(sizeof(hash_table_t));
+	if (table == NULL) {
+		return(NULL);
+	}
+
+	array = (hash_cell_t*) malloc(sizeof(hash_cell_t) * prime);
+	if (array == NULL) {
+		free(table);
+		return(NULL);
+	}
+
+	table->array = array;
+	table->n_cells = prime;
+	table->n_mutexes = 0;
+	table->mutexes = NULL;
+	table->heaps = NULL;
+	table->heap = NULL;
+	table->magic_n = HASH_TABLE_MAGIC_N;
+
+	/* Initialize the cell array */
+	hash_table_clear(table);
+
+	return(table);
+}
+
+/*****************************************************************
+Frees a hash table. */
+static
+void
+wdl_hash_table_free(
+/*================*/
+	hash_table_t*	table)	/* in, own: hash table */
+{
+	ut_a(table != NULL);
+	ut_a(table->mutexes == NULL);
+
+	free(table->array);
+	free(table);
+}
+
+/***********************************************************************
+Function for calculating the count of imports given the base of the IAT. */
+static
+ulint
+wdl_import_count(
+/*=============*/
+					/* out: number of imports */
+	PCImgThunkData	pitd_base)	/* in: base of the IAT */
+{
+	ulint		ret = 0;
+	PCImgThunkData	pitd = pitd_base;
+
+	while (pitd->u1.Function) {
+		pitd++;
+		ret++;
+	}
+
+	return(ret);
+}
+
+/***********************************************************************
+Read Mapfile to a hashtable for faster access */
+static
+ibool
+wdl_load_mapfile(
+/*=============*/
+					/* out: TRUE if the mapfile is
+					loaded successfully. */
+	const char*	filename)	/* in: name of the mapfile. */
+{
+	FILE*		fp;
+	const size_t	nSize = 256;
+	char		tmp_buf[nSize];
+	char*		func_name;
+	char*		func_addr;
+	ulint		load_addr = 0;
+	ibool		valid_load_addr = FALSE;
+
+	fp = fopen(filename, "r");
+	if (fp == NULL) {
+
+		return(FALSE);
+	}
+
+	/* Check whether to create the hashtable */
+	if (m_htbl == NULL) {
+
+		m_htbl = wdl_hash_create(MAP_HASH_CELLS_NUM);
+
+		if (m_htbl == NULL) {
+
+			fclose(fp);
+			return(FALSE);
+		}
+	}
+
+	/* Search start of symbol list and get the preferred load address */
+	while (fgets(tmp_buf, sizeof(tmp_buf), fp)) {
+
+		if (sscanf(tmp_buf, " Preferred load address is %16X",
+			   &load_addr) == 1) {
+
+			valid_load_addr = TRUE;
+		}
+
+		if (strstr(tmp_buf, "Rva+Base") != NULL) {
+
+			break;
+		}
+	}
+
+	if (valid_load_addr == FALSE) {
+
+		/* No "Preferred load address", the map file is wrong. */
+		fclose(fp);
+		return(FALSE);
+	}
+
+	/* Read symbol list */
+	while (fgets(tmp_buf, sizeof(tmp_buf), fp))
+	{
+		map_hash_chain_t*	map_cell;
+		ulint			map_fold;
+
+		if (*tmp_buf == 0) {
+
+			continue;
+		}
+
+		func_name = strtok(tmp_buf, " ");
+		func_name = strtok(NULL, " ");
+		func_addr = strtok(NULL, " ");
+
+		if (func_name && func_addr) {
+
+			ut_snprintf(tmp_buf, nSize, "0x%s", func_addr);
+			if (*func_name == '_') {
+
+				func_name++;
+			}
+
+			map_cell = (map_hash_chain_t*)
+				   malloc(sizeof(map_hash_chain_t));
+			if (map_cell == NULL) {
+				return(FALSE);
+			}
+
+			/* Chain all cells together */
+			map_cell->chain = chain_header;
+			chain_header = map_cell;
+
+			map_cell->symbol = strdup(func_name);
+			map_cell->value = strtoul(tmp_buf, NULL, 0)
+					  - load_addr;
+			map_fold = ut_fold_string(map_cell->symbol);
+
+			HASH_INSERT(map_hash_chain_t,
+				    next,
+				    m_htbl,
+				    map_fold,
+				    map_cell);
+		}
+	}
+
+	fclose(fp);
+
+	return(TRUE);
+}
+
+/*****************************************************************
+Cleanup.during DLL unload */
+static
+void
+wdl_cleanup(void)
+/*=============*/
+{
+	while (chain_header != NULL) {
+		map_hash_chain_t*	tmp;
+
+		tmp = chain_header->chain;
+		free(chain_header->symbol);
+		free(chain_header);
+		chain_header = tmp;
+	}
+
+	if (m_htbl != NULL) {
+
+		wdl_hash_table_free(m_htbl);
+	}
+}
+
+/***********************************************************************
+Load the mapfile mysqld.map. */
+static
+HMODULE
+wdl_get_mysqld_mapfile(void)
+/*========================*/
+			/* out: the module handle */
+{
+	char	file_name[MAX_PATH];
+	char*	ext;
+	ulint	err;
+
+	if (my_hmod == 0) {
+
+		size_t	nSize = MAX_PATH - strlen(".map") -1;
+
+		/* First find out the name of current executable */
+		my_hmod = GetModuleHandle(NULL);
+		if (my_hmod == 0) {
+
+			return(my_hmod);
+		}
+
+		err = GetModuleFileName(my_hmod, file_name, nSize);
+		if (err == 0) {
+
+			my_hmod = 0;
+			return(my_hmod);
+		}
+
+		ext = strrchr(file_name, '.');
+		if (ext != NULL) {
+
+			*ext = 0;
+			strcat(file_name, ".map");
+
+			err = wdl_load_mapfile(file_name);
+			if (err == 0) {
+
+				my_hmod = 0;
+			}
+		} else {
+
+			my_hmod = 0;
+		}
+	}
+
+	return(my_hmod);
+}
+
+/***********************************************************************
+Retrieves the address of an exported function. It follows the convention
+of GetProcAddress(). */
+static
+FARPROC
+wdl_get_procaddr_from_map(
+/*======================*/
+					/* out: address of exported
+					function. */
+	HANDLE		m_handle,	/* in: module handle */
+	const char*	import_proc)	/* in: procedure name */
+{
+	map_hash_chain_t*	hash_chain;
+	ulint			map_fold;
+
+	map_fold = ut_fold_string(import_proc);
+	HASH_SEARCH(
+		next,
+		m_htbl,
+		map_fold,
+		map_hash_chain_t*,
+		hash_chain,
+		(ut_strcmp(hash_chain->symbol, import_proc) == 0));
+
+	if (hash_chain == NULL) {
+
+#ifdef _WIN64
+		/* On Win64, the leading '_' may not be taken out. In this
+		case, search again without the leading '_'. */
+		if (*import_proc == '_') {
+
+			import_proc++;
+		}
+
+		map_fold = ut_fold_string(import_proc);
+		HASH_SEARCH(
+			next,
+			m_htbl,
+			map_fold,
+			map_hash_chain_t*,
+			hash_chain,
+			(ut_strcmp(hash_chain->symbol, import_proc) == 0));
+
+		if (hash_chain == NULL) {
+#endif
+			if (wdl_init == TRUE) {
+
+				sql_print_error(
+					"InnoDB: the procedure pointer of %s"
+					" is not found.",
+					import_proc);
+			}
+
+			return(0);
+#ifdef _WIN64
+		}
+#endif
+	}
+
+	return((FARPROC) ((ulint) m_handle + hash_chain->value));
+}
+
+/***********************************************************************
+Retrieves the address of an exported variable.
+Note: It does not follow the Windows call convention FARPROC. */
+static
+void*
+wdl_get_varaddr_from_map(
+/*=====================*/
+						/* out: address of exported
+						variable. */
+	HANDLE		m_handle,		/* in: module handle */
+	const char*	import_variable)	/* in: variable name */
+{
+	map_hash_chain_t*	hash_chain;
+	ulint			map_fold;
+
+	map_fold = ut_fold_string(import_variable);
+	HASH_SEARCH(
+		next,
+		m_htbl,
+		map_fold,
+		map_hash_chain_t*,
+		hash_chain,
+		(ut_strcmp(hash_chain->symbol, import_variable) == 0));
+
+	if (hash_chain == NULL) {
+
+#ifdef _WIN64
+		/* On Win64, the leading '_' may not be taken out. In this
+		case, search again without the leading '_'. */
+		if (*import_variable == '_') {
+
+			import_variable++;
+		}
+
+		map_fold = ut_fold_string(import_variable);
+		HASH_SEARCH(
+			next,
+			m_htbl,
+			map_fold,
+			map_hash_chain_t*,
+			hash_chain,
+			(ut_strcmp(hash_chain->symbol, import_variable) == 0));
+
+		if (hash_chain == NULL) {
+#endif
+			if (wdl_init == TRUE) {
+
+				sql_print_error(
+					"InnoDB: the variable address of %s"
+					" is not found.",
+					import_variable);
+			}
+
+			return(0);
+#ifdef _WIN64
+		}
+#endif
+	}
+
+	return((void*) ((ulint) m_handle + hash_chain->value));
+}
+
+/***********************************************************************
+Bind all unresolved external variables from the MySQL executable. */
+static
+bool
+wdl_get_external_variables(void)
+/*============================*/
+			/* out: TRUE if successful */
+{
+	HMODULE	hmod = wdl_get_mysqld_mapfile();
+
+	if (hmod == 0) {
+
+		return(FALSE);
+	}
+
+#define GET_SYM(sym, var, type)					\
+	var = (type*) wdl_get_varaddr_from_map(hmod, sym);	\
+	if (var == NULL) return(FALSE)
+#ifdef _WIN64
+#define GET_SYM2(sym1, sym2, var, type)				\
+	var = (type*) wdl_get_varaddr_from_map(hmod, sym1);	\
+	if (var == NULL) return(FALSE)
+#else
+#define GET_SYM2(sym1, sym2, var, type)				\
+	var = (type*) wdl_get_varaddr_from_map(hmod, sym2);	\
+	if (var == NULL) return(FALSE)
+#endif // (_WIN64)
+#define GET_C_SYM(sym, type) GET_SYM(#sym, wdl_##sym, type)
+#define GET_PROC_ADDR(sym)					\
+	wdl##sym = (pfn##sym) wdl_get_procaddr_from_map(hmod, #sym)
+
+	GET_C_SYM(my_charset_bin, CHARSET_INFO);
+	GET_C_SYM(my_charset_latin1, CHARSET_INFO);
+	GET_C_SYM(my_charset_filename, CHARSET_INFO);
+	GET_C_SYM(default_charset_info, CHARSET_INFO*);
+	GET_C_SYM(all_charsets, CHARSET_INFO*);
+	GET_C_SYM(my_umask, int);
+
+	GET_SYM("?global_system_variables@@3Usystem_variables@@A",
+		wdl_global_system_variables, struct system_variables);
+	GET_SYM("?mysql_real_data_home@@3PADA",
+		wdl_mysql_real_data_home, char);
+	GET_SYM("?reg_ext@@3PADA", wdl_reg_ext, char);
+	GET_SYM("?LOCK_thread_count@@3U_RTL_CRITICAL_SECTION@@A",
+		wdl_LOCK_thread_count, pthread_mutex_t);
+	GET_SYM("?key_map_full@@3V?$Bitmap@$0EA@@@A",
+		wdl_key_map_full, key_map);
+	GET_SYM("?mysql_tmpdir_list@@3Ust_my_tmpdir@@A",
+		wdl_mysql_tmpdir_list, MY_TMPDIR);
+	GET_SYM("?mysqld_embedded@@3_NA",
+		wdl_mysqld_embedded, bool);
+	GET_SYM("?lower_case_table_names@@3IA",
+		wdl_lower_case_table_names, uint);
+	GET_SYM("?specialflag@@3KA", wdl_specialflag, ulong);
+	GET_SYM("?builtin_innobase_plugin@@3PAUst_mysql_plugin@@A",
+		builtin_innobase_plugin_ptr, struct st_mysql_plugin);
+	GET_SYM("?opt_bin_log@@3_NA",
+		wdl_opt_bin_log, bool);
+
+	GET_SYM2("?system_charset_info@@3PEAUcharset_info_st@@EA",
+		 "?system_charset_info@@3PAUcharset_info_st@@A",
+		 wdl_system_charset_info, CHARSET_INFO*);
+	GET_SYM2("?mysql_data_home@@3PEADEA",
+		 "?mysql_data_home@@3PADA",
+		 wdl_mysql_data_home, char*);
+	GET_SYM2("?tx_isolation_names@@3PAPEBDA",
+		 "?tx_isolation_names@@3PAPBDA",
+		 wdl_tx_isolation_names, char*);
+	GET_SYM2("?binlog_format_names@@3PAPEBDA",
+		 "?binlog_format_names@@3PAPBDA",
+		 wdl_binlog_format_names, char*);
+
+#ifndef DBUG_OFF
+	GET_PROC_ADDR(_db_enter_);
+	GET_PROC_ADDR(_db_return_);
+	GET_PROC_ADDR(_db_pargs_);
+	GET_PROC_ADDR(_db_doprnt_);
+	GET_PROC_ADDR(_db_dump_);
+
+	/* If any of the dbug functions is not available, just make them
+	all invalid. This is the case when working with a non-debug
+	version of the server. */
+	if (wdl_db_enter_ == NULL || wdl_db_return_ == NULL
+	    || wdl_db_pargs_ == NULL || wdl_db_doprnt_ == NULL
+	    || wdl_db_dump_ == NULL) {
+
+		wdl_db_enter_ = NULL;
+		wdl_db_return_ = NULL;
+		wdl_db_pargs_ = NULL;
+		wdl_db_doprnt_ = NULL;
+		wdl_db_dump_ = NULL;
+	}
+#endif /* !DBUG_OFF */
+
+	wdl_init = TRUE;
+	return(TRUE);
+
+#undef GET_SYM
+#undef GET_SYM2
+#undef GET_C_SYM
+#undef GET_PROC_ADDR
+}
+
+/***********************************************************************
+The DLL Delayed Loading Helper Function for resolving externals.
+
+The function may fail due to one of the three reasons:
+
+* Invalid parameter, which happens if the attributes in pidd aren't
+  specified correctly.
+* Failed to load the map file mysqld.map.
+* Failed to find an external name in the map file mysqld.map.
+
+Note: this function is called by run-time as well as __HrLoadAllImportsForDll.
+So, it has to follow Windows call convention. */
+extern "C"
+FARPROC WINAPI
+__delayLoadHelper2(
+/*===============*/
+					/* out: the address of the imported
+					function*/
+	PCImgDelayDescr	pidd,		/* in: a const pointer to a
+					ImgDelayDescr, see delayimp.h. */
+	FARPROC*	iat_entry)	/* in/out: A pointer to the slot in
+					the delay load import address table
+					to be updated with the address of the
+					imported function. */
+{
+	ulint		iIAT, iINT;
+	HMODULE		hmod;
+	PCImgThunkData	pitd;
+	FARPROC		fun = NULL;
+
+	/* Set up data used for the hook procs  */
+	InternalImgDelayDescr	idd = {
+				pidd->grAttrs,
+				PFromRva<LPCSTR>(pidd->rvaDLLName),
+				PFromRva<HMODULE*>(pidd->rvaHmod),
+				PFromRva<PImgThunkData>(pidd->rvaIAT),
+				PFromRva<PCImgThunkData>(pidd->rvaINT),
+				PFromRva<PCImgThunkData>(pidd->rvaBoundIAT),
+				PFromRva<PCImgThunkData>(pidd->rvaUnloadIAT),
+				pidd->dwTimeStamp
+	};
+
+	DelayLoadInfo		dli = {
+				sizeof(DelayLoadInfo),
+				pidd,
+				iat_entry,
+				idd.szName,
+				{0},
+				0,
+				0,
+				0
+	};
+
+	/* Check the Delay Load Attributes, log an error of invalid
+	parameter, which happens if the attributes in pidd are not
+	specified correctly. */
+	if ((idd.grAttrs & dlattrRva) == 0) {
+
+		sql_print_error("InnoDB: invalid parameter for delay loader.");
+		return(0);
+	}
+
+	hmod = *idd.phmod;
+
+	/* Calculate the index for the IAT entry in the import address table.
+	The INT entries are ordered the same as the IAT entries so the
+	calculation can be done on the IAT side. */
+	iIAT = (PCImgThunkData) iat_entry - idd.pIAT;
+	iINT = iIAT;
+
+	pitd = &(idd.pINT[iINT]);
+
+	dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pitd->u1.Ordinal);
+
+	if (dli.dlp.fImportByName) {
+
+		dli.dlp.szProcName = (LPCSTR) (PFromRva<PIMAGE_IMPORT_BY_NAME>
+			((RVA) ((UINT_PTR) pitd->u1.AddressOfData))->Name);
+	} else {
+
+		dli.dlp.dwOrdinal = (ulint) IMAGE_ORDINAL(pitd->u1.Ordinal);
+	}
+
+	/* Now, load the mapfile, if it has not been done yet */
+	if (hmod == 0) {
+
+		hmod = wdl_get_mysqld_mapfile();
+	}
+
+	if (hmod == 0) {
+		/* LoadLibrary failed. */
+		PDelayLoadInfo	rgpdli[1] = {&dli};
+
+		dli.dwLastError = ::GetLastError();
+
+		sql_print_error(
+			"InnoDB: failed to load mysqld.map with error %d.",
+			dli.dwLastError);
+
+		return(0);
+	}
+
+	/* Store the library handle. */
+	idd.phmod = &hmod;
+
+	/* Go for the procedure now. */
+	dli.hmodCur = hmod;
+
+	if (pidd->rvaBoundIAT && pidd->dwTimeStamp) {
+
+		/* Bound imports exist, check the timestamp from the target
+		image */
+		PIMAGE_NT_HEADERS	pinh;
+
+		pinh = (PIMAGE_NT_HEADERS) ((byte*) hmod
+				+ ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
+
+		if (pinh->Signature == IMAGE_NT_SIGNATURE
+		    && pinh->FileHeader.TimeDateStamp == idd.dwTimeStamp
+		    && (DWORD) hmod == pinh->OptionalHeader.ImageBase) {
+
+			/* We have a decent address in the bound IAT. */
+			fun = (FARPROC) (UINT_PTR)
+					idd.pBoundIAT[iIAT].u1.Function;
+
+			if (fun) {
+
+				*iat_entry = fun;
+				return(fun);
+			}
+		}
+	}
+
+	fun = wdl_get_procaddr_from_map(hmod, dli.dlp.szProcName);
+
+	if (fun == 0) {
+
+		return(0);
+	}
+
+	*iat_entry = fun;
+	return(fun);
+}
+
+/***********************************************************************
+Unload a DLL that was delay loaded. This function is called by run-time. */
+extern "C"
+BOOL WINAPI
+__FUnloadDelayLoadedDLL2(
+/*=====================*/
+				/* out: TRUE is returned if the DLL is found
+				and the IAT matches the original one. */
+	LPCSTR	module_name)	/* in: DLL name */
+{
+	return(TRUE);
+}
+
+/******************************************************************
+Load all imports from a DLL that was specified with the /delayload linker
+option.
+Note: this function is called by run-time. So, it has to follow Windows call
+convention. */
+extern "C"
+HRESULT WINAPI
+__HrLoadAllImportsForDll(
+/*=====================*/
+				/* out: S_OK if the DLL matches, otherwise
+				ERROR_MOD_NOT_FOUND is returned. */
+	LPCSTR	module_name)	/* in: DLL name */
+{
+	PIMAGE_NT_HEADERS	img;
+	PCImgDelayDescr		pidd;
+	IMAGE_DATA_DIRECTORY*	image_data;
+	LPCSTR			current_module;
+	HRESULT			ret = ERROR_MOD_NOT_FOUND;
+	HMODULE			hmod = (HMODULE) &__ImageBase;
+
+	img = (PIMAGE_NT_HEADERS) ((byte*) hmod
+				   + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
+	image_data =
+	 &img->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
+
+	/* Scan the delay load IAT/INT for the DLL */
+	if (image_data->Size) {
+
+		pidd = PFromRva<PCImgDelayDescr>(image_data->VirtualAddress);
+
+		/* Check all of the listed DLLs we want to load. */
+		while (pidd->rvaDLLName) {
+
+			current_module = PFromRva<LPCSTR>(pidd->rvaDLLName);
+
+			if (stricmp(module_name, current_module) == 0) {
+
+				/* Found it, break out with pidd and
+				current_module set appropriately */
+				break;
+			}
+
+			/* To the next delay import descriptor */
+			pidd++;
+		}
+
+		if (pidd->rvaDLLName) {
+
+			/* Found a matching DLL, now process it. */
+			FARPROC*	iat_entry;
+			size_t		count;
+
+			iat_entry = PFromRva<FARPROC*>(pidd->rvaIAT);
+			count = wdl_import_count((PCImgThunkData) iat_entry);
+
+			/* now load all the imports from the DLL */
+			while (count > 0) {
+
+				/* No need to check the return value */
+				__delayLoadHelper2(pidd, iat_entry);
+				iat_entry++;
+				count--;
+			}
+
+			ret = S_OK;
+		}
+	}
+
+	return ret;
+}
+
+/******************************************************************
+The main function of a DLL */
+BOOL
+WINAPI
+DllMain(
+/*====*/
+					/* out: TRUE if the call succeeds */
+	HINSTANCE	hinstDLL,	/* in: handle to the DLL module */
+	DWORD		fdwReason,	/* Reason code that indicates why the
+					DLL entry-point function is being
+					called.*/
+	LPVOID		lpvReserved)	/* in: additional parameter based on
+					fdwReason */
+{
+	BOOL	success = TRUE;
+
+	switch (fdwReason) {
+
+	case DLL_PROCESS_ATTACH:
+		success = wdl_get_external_variables();
+		break;
+
+	case DLL_PROCESS_DETACH:
+		wdl_cleanup();
+		break;
+	}
+
+	return(success);
+}
+
+#ifndef DBUG_OFF
+/******************************************************************
+Process entry point to user function. It makes the call to _db_enter_
+in mysqld.exe. The DBUG functions are defined in my_dbug.h. */
+extern "C" UNIV_INTERN
+void
+_db_enter_(
+	const char*	_func_,		/* in: current function name */
+	const char*	_file_,		/* in: current file name */
+	uint		_line_,		/* in: current source line number */
+	const char**	_sfunc_,	/* out: previous _func_ */
+	const char**	_sfile_,	/* out: previous _file_ */
+	uint*		_slevel_,	/* out: previous nesting level */
+	char***		_sframep_)	/* out: previous frame pointer */
+{
+	if (wdl_db_enter_ != NULL) {
+
+		wdl_db_enter_(_func_, _file_, _line_, _sfunc_, _sfile_,
+			      _slevel_, _sframep_);
+	}
+}
+
+/******************************************************************
+Process exit from user function. It makes the call to _db_return_()
+in the server. */
+extern "C" UNIV_INTERN
+void
+_db_return_(
+	uint		_line_,		/* in: current source line number */
+	const char**	_sfunc_,	/* out: previous _func_ */
+	const char**	_sfile_,	/* out: previous _file_ */
+	uint*		_slevel_)	/* out: previous level */
+{
+	if (wdl_db_return_ != NULL) {
+
+		wdl_db_return_(_line_, _sfunc_, _sfile_, _slevel_);
+	}
+}
+
+/******************************************************************
+Log arguments for subsequent use. It makes the call to _db_pargs_()
+in the server. */
+extern "C" UNIV_INTERN
+void
+_db_pargs_(
+	uint		_line_,		/* in: current source line number */
+	const char*	keyword)	/* in: keyword for current macro */
+{
+	if (wdl_db_pargs_ != NULL) {
+
+		wdl_db_pargs_(_line_, keyword);
+	}
+}
+
+/******************************************************************
+Handle print of debug lines. It saves the text into a buffer first,
+then makes the call to _db_doprnt_() in the server. The text is
+truncated to the size of buffer. */
+extern "C" UNIV_INTERN
+void
+_db_doprnt_(
+	const char*	format,		/* in: the format string */
+	...)				/* in: list of arguments */
+{
+	va_list		argp;
+	char		buffer[512];
+
+	if (wdl_db_doprnt_ != NULL) {
+
+		va_start(argp, format);
+		/* it is ok to ignore the trunction. */
+		_vsnprintf(buffer, sizeof(buffer), format, argp);
+		wdl_db_doprnt_(buffer);
+		va_end(argp);
+	}
+}
+
+/******************************************************************
+Dump a string in hex. It makes the call to _db_dump_() in the server. */
+extern "C" UNIV_INTERN
+void
+_db_dump_(
+	uint			_line_,		/* in: current source line
+						number */
+	const char*		keyword,	/* in: keyword list */
+	const unsigned char*	memory,		/* in: memory to dump */
+	size_t			length)		/* in: bytes to dump */
+{
+	if (wdl_db_dump_ != NULL) {
+
+		wdl_db_dump_(_line_, keyword, memory, length);
+	}
+}
+
+#endif /* !DBUG_OFF */
+#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */