From 96d97031d6a45ecd09fb61e82d624af61a2e7ccc Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Sun, 13 Aug 2006 16:49:43 +0000 Subject: [PATCH] Added a Win32 dll loader for loading/unloading *.prg and *.dsc files. It requires at least WinXP as it uses GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS flag for unloading. The "self-unloading" via LOADER_UNLOAD() is implemented by defering the actual unload until back in the main loop using a user-mode APC (Asynchronous Procedure Call). --- platform/win32/loader/dll-loader.c | 113 +++++++++++++++++++++++++++++ platform/win32/loader/dll-loader.h | 43 +++++++++++ 2 files changed, 156 insertions(+) create mode 100644 platform/win32/loader/dll-loader.c create mode 100644 platform/win32/loader/dll-loader.h diff --git a/platform/win32/loader/dll-loader.c b/platform/win32/loader/dll-loader.c new file mode 100644 index 000000000..611a2e40d --- /dev/null +++ b/platform/win32/loader/dll-loader.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Oliver Schmidt + * + * $Id: dll-loader.c,v 1.1 2006/08/13 16:49:43 oliverschmidt Exp $ + */ + +#define WIN32_LEAN_AND_MEAN +#define _WIN32_WINNT 0x0501 +#include + +#include "contiki.h" + +/*---------------------------------------------------------------------------*/ +int +dll_loader_load(char *name, char *arg) +{ + HMODULE handle; + struct process **p; + + /* Load and link the program. */ + handle = LoadLibrary(name); + + if(handle == NULL) { + debug_printf("dll_loader_load: loading failed: %d\n", GetLastError()); + return LOADER_ERR_OPEN; + } + + /* Find the main process of the loaded program. */ + p = (struct process **)GetProcAddress(handle, "process_load"); + if(p == NULL) { + debug_printf("dll_loader_load: could not find process startpoint 'process_load'\n"); + return LOADER_ERR_READ; + } + + /* Start the process. */ + debug_printf("Starting '%s'\n", (*p)->name); + process_start(*p, arg); + + return LOADER_OK; +} +/*---------------------------------------------------------------------------*/ +void +dll_loader_unload(void *addr) +{ + /* Avoid Access Violation Exception due to unloading code still being executed. */ + QueueUserAPC((PAPCFUNC)dll_loader_unload_dsc, GetCurrentThread(), (ULONG_PTR)addr); +} +/*---------------------------------------------------------------------------*/ +struct dsc * +dll_loader_load_dsc(char *name) +{ + HMODULE handle; + char symbol[24]; + struct dsc *d; + + handle = LoadLibrary(name); + + if(handle == NULL) { + debug_printf("dll_loader_load_dsc: loading failed: %d\n", GetLastError()); + return NULL; + } + + strcpy(symbol, name); + *strchr(symbol, '.') = '_'; + + d = (struct dsc *)GetProcAddress(handle, symbol); + if(d == NULL) { + debug_printf("dll_loader_load_dsc: could not find symbol '%s'\n", symbol); + return NULL; + } + + return d; +} +/*---------------------------------------------------------------------------*/ +void __stdcall +dll_loader_unload_dsc(void *addr) +{ + HMODULE handle; + + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, addr, &handle); + FreeLibrary(handle); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/win32/loader/dll-loader.h b/platform/win32/loader/dll-loader.h new file mode 100644 index 000000000..e546816f3 --- /dev/null +++ b/platform/win32/loader/dll-loader.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Oliver Schmidt + * + * $Id: dll-loader.h,v 1.1 2006/08/13 16:49:43 oliverschmidt Exp $ + */ +#ifndef __DLL_LOADER_H__ +#define __DLL_LOADER_H__ + +CCI int dll_loader_load(char *name, char *arg); +CCI void dll_loader_unload(void *addr); +CCI struct dsc *dll_loader_load_dsc(char *name); +CCI void __stdcall dll_loader_unload_dsc(void *addr); + +#endif /* __DLL_LOADER_H__ */