2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
22 #include "DllLoader.h"
23 #include "DllLoaderContainer.h"
24 #include "dll_tracker.h"
27 #include "filesystem/SpecialProtocol.h"
28 #include "utils/log.h"
30 #define DEFAULT_DLLPATH "special://xbmc/system/players/mplayer/codecs/"
31 #define HIGH_WORD(a) ((uintptr_t)(a) >> 16)
32 #define LOW_WORD(a) ((WORD)(((uintptr_t)(a)) & MAXWORD))
36 char* getpath(char *buf, const char *full)
39 if ((pos = strrchr(full, PATH_SEPARATOR_CHAR)))
41 strncpy(buf, full, pos - full + 1 );
42 buf[pos - full + 1] = 0;
52 extern "C" HMODULE __stdcall dllLoadLibraryExtended(LPCSTR lib_file, LPCSTR sourcedll)
54 char libname[MAX_PATH + 1] = {};
55 char libpath[MAX_PATH + 1] = {};
56 LibraryLoader* dll = NULL;
59 const char* p = strrchr(lib_file, PATH_SEPARATOR_CHAR);
63 strcpy(libname, lib_file);
65 if( libname[0] == '\0' )
69 getpath(libpath, lib_file);
73 /* also check for invalid paths wich begin with a \ */
74 if( libpath[0] == '\0' || libpath[0] == PATH_SEPARATOR_CHAR )
76 /* use calling dll's path as base address for this call */
77 getpath(libpath, sourcedll);
79 /* mplayer has all it's dlls in a codecs subdirectory */
80 if (strstr(sourcedll, "mplayer.dll"))
81 strcat(libpath, "codecs\\");
85 /* if we still don't have a path, use default path */
86 if( libpath[0] == '\0' )
87 strcpy(libpath, DEFAULT_DLLPATH);
90 /* "If no file name extension is specified in the lpFileName parameter, the default library extension .dll is appended. */
91 /* However, the file name string can include a trailing point character (.) to indicate that the module name has no extension." */
92 if( strrchr(libname, '.') == NULL )
93 strcat(libname, ".dll");
94 else if( libname[strlen(libname)-1] == '.' )
95 libname[strlen(libname)-1] = '\0';
97 dll = DllLoaderContainer::LoadModule(libname, libpath);
100 return (HMODULE)dll->GetHModule();
102 CLog::Log(LOGERROR, "LoadLibrary('%s') failed", libname);
106 extern "C" HMODULE __stdcall dllLoadLibraryA(LPCSTR file)
108 return dllLoadLibraryExtended(file, NULL);
111 #define DONT_RESOLVE_DLL_REFERENCES 0x00000001
112 #define LOAD_LIBRARY_AS_DATAFILE 0x00000002
113 #define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008
114 #define LOAD_IGNORE_CODE_AUTHZ_LEVEL 0x00000010
116 extern "C" HMODULE __stdcall dllLoadLibraryExExtended(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags, LPCSTR sourcedll)
121 if (dwFlags & DONT_RESOLVE_DLL_REFERENCES) strcat(strFlags, "\n - DONT_RESOLVE_DLL_REFERENCES");
122 if (dwFlags & LOAD_IGNORE_CODE_AUTHZ_LEVEL) strcat(strFlags, "\n - LOAD_IGNORE_CODE_AUTHZ_LEVEL");
123 if (dwFlags & LOAD_LIBRARY_AS_DATAFILE) strcat(strFlags, "\n - LOAD_LIBRARY_AS_DATAFILE");
124 if (dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH) strcat(strFlags, "\n - LOAD_WITH_ALTERED_SEARCH_PATH");
126 CLog::Log(LOGDEBUG, "LoadLibraryExA called with flags: %s", strFlags);
128 return dllLoadLibraryExtended(lpLibFileName, sourcedll);
131 extern "C" HMODULE __stdcall dllLoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
133 return dllLoadLibraryExExtended(lpLibFileName, hFile, dwFlags, NULL);
136 extern "C" BOOL __stdcall dllFreeLibrary(HINSTANCE hLibModule)
138 LibraryLoader* dllhandle = DllLoaderContainer::GetModule(hLibModule);
142 CLog::Log(LOGERROR, "%s - Invalid hModule specified",__FUNCTION__);
146 // to make sure systems dlls are never deleted
147 if (dllhandle->IsSystemDll()) return 1;
149 DllLoaderContainer::ReleaseModule(dllhandle);
154 extern "C" FARPROC __stdcall dllGetProcAddress(HMODULE hModule, LPCSTR function)
156 uintptr_t loc = (uintptr_t)_ReturnAddress();
158 void* address = NULL;
159 LibraryLoader* dll = DllLoaderContainer::GetModule(hModule);
163 CLog::Log(LOGERROR, "%s - Invalid hModule specified",__FUNCTION__);
167 /* how can somebody get the stupid idea to create such a stupid function */
168 /* where you never know if the given pointer is a pointer or a value */
169 if( HIGH_WORD(function) == 0 && LOW_WORD(function) < 1000)
171 if( dll->ResolveOrdinal(LOW_WORD(function), &address) )
173 CLog::Log(LOGDEBUG, "%s(%p(%s), %d) => %p", __FUNCTION__, hModule, dll->GetName(), LOW_WORD(function), address);
175 else if( dll->IsSystemDll() )
178 sprintf(ordinal, "%d", LOW_WORD(function));
179 address = (void*)create_dummy_function(dll->GetName(), ordinal);
181 /* add to tracklist if we are tracking this source dll */
182 DllTrackInfo* track = tracker_get_dlltrackinfo(loc);
184 tracker_dll_data_track(track->pDll, (uintptr_t)address);
186 CLog::Log(LOGDEBUG, "%s - created dummy function %s!%s",__FUNCTION__, dll->GetName(), ordinal);
191 CLog::Log(LOGDEBUG, "%s(%p(%s), '%s') => %p",__FUNCTION__ , hModule, dll->GetName(), function, address);
196 if( dll->ResolveExport(function, &address) )
198 CLog::Log(LOGDEBUG, "%s(%p(%s), '%s') => %p",__FUNCTION__ , hModule, dll->GetName(), function, address);
202 DllTrackInfo* track = tracker_get_dlltrackinfo(loc);
203 /* some dll's require us to always return a function or it will fail, other's */
204 /* decide functionallity depending on if the functions exist and may fail */
205 if( dll->IsSystemDll() && track
206 && stricmp(track->pDll->GetName(), "CoreAVCDecoder.ax") == 0 )
208 address = (void*)create_dummy_function(dll->GetName(), function);
209 tracker_dll_data_track(track->pDll, (uintptr_t)address);
210 CLog::Log(LOGDEBUG, "%s - created dummy function %s!%s", __FUNCTION__, dll->GetName(), function);
215 CLog::Log(LOGDEBUG, "%s(%p(%s), '%s') => %p", __FUNCTION__, hModule, dll->GetName(), function, address);
220 return (FARPROC)address;
223 extern "C" HMODULE WINAPI dllGetModuleHandleA(LPCSTR lpModuleName)
226 If the file name extension is omitted, the default library extension .dll is appended.
227 The file name string can include a trailing point character (.) to indicate that the module name has no extension.
228 The string does not have to specify a path. When specifying a path, be sure to use backslashes (\), not forward slashes (/).
229 The name is compared (case independently)
230 If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file).
233 if( lpModuleName == NULL )
236 char* strModuleName = new char[strlen(lpModuleName) + 5];
237 strcpy(strModuleName, lpModuleName);
239 if (strrchr(strModuleName, '.') == 0) strcat(strModuleName, ".dll");
241 //CLog::Log(LOGDEBUG, "GetModuleHandleA(%s) .. looking up", lpModuleName);
243 LibraryLoader *p = DllLoaderContainer::GetModule(strModuleName);
244 delete []strModuleName;
248 //CLog::Log(LOGDEBUG, "GetModuleHandleA('%s') => 0x%x", lpModuleName, h);
249 return (HMODULE)p->GetHModule();
252 CLog::Log(LOGDEBUG, "GetModuleHandleA('%s') failed", lpModuleName);
256 extern "C" DWORD WINAPI dllGetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize)
261 return GetModuleFileNameA(hModule, lpFilename, nSize);
263 CLog::Log(LOGDEBUG, "%s - No hModule specified", __FUNCTION__);
268 LibraryLoader* dll = DllLoaderContainer::GetModule(hModule);
271 CLog::Log(LOGERROR, "%s - Invalid hModule specified", __FUNCTION__);
275 char* sName = dll->GetFileName();
278 strncpy(lpFilename, sName, nSize);
279 lpFilename[nSize] = 0;
280 return strlen(lpFilename);