[WASAPI] set stream audio category
[xbmc.git] / xbmc / cores / DllLoader / DllLoaderContainer.cpp
blob28242ce40dd28fea7ef2dd3c01a193a2f2514984
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "DllLoaderContainer.h"
10 #ifdef TARGET_POSIX
11 #include "SoLoader.h"
12 #endif
13 #ifdef TARGET_WINDOWS
14 #include "Win32DllLoader.h"
15 #endif
16 #include "URL.h"
17 #include "filesystem/File.h"
18 #include "utils/StringUtils.h"
19 #include "utils/URIUtils.h"
20 #include "utils/log.h"
22 #if defined(TARGET_WINDOWS)
23 #define ENV_PARTIAL_PATH \
24 "special://xbmcbin/;" \
25 "special://xbmcbin/system/;" \
26 "special://xbmcbin/system/python/;" \
27 "special://xbmc/;" \
28 "special://xbmc/system/;" \
29 "special://xbmc/system/python/"
30 #else
31 #define ENV_PARTIAL_PATH \
32 "special://xbmcbin/system/;" \
33 "special://xbmcbin/system/players/mplayer/;" \
34 "special://xbmcbin/system/players/VideoPlayer/;" \
35 "special://xbmcbin/system/players/paplayer/;" \
36 "special://xbmcbin/system/python/;" \
37 "special://xbmc/system/;" \
38 "special://xbmc/system/players/mplayer/;" \
39 "special://xbmc/system/players/VideoPlayer/;" \
40 "special://xbmc/system/players/paplayer/;" \
41 "special://xbmc/system/python/"
42 #endif
43 #if defined(TARGET_DARWIN)
44 #define ENV_PATH ENV_PARTIAL_PATH \
45 ";special://frameworks/"
46 #else
47 #define ENV_PATH ENV_PARTIAL_PATH
48 #endif
50 //Define this to get logging on all calls to load/unload of dlls
51 //#define LOGALL
54 using namespace XFILE;
56 LibraryLoader* DllLoaderContainer::m_dlls[64] = {};
57 int DllLoaderContainer::m_iNrOfDlls = 0;
59 LibraryLoader* DllLoaderContainer::GetModule(const char* sName)
61 for (int i = 0; i < m_iNrOfDlls && m_dlls[i] != NULL; i++)
63 if (StringUtils::CompareNoCase(m_dlls[i]->GetName(), sName) == 0)
64 return m_dlls[i];
65 if (!m_dlls[i]->IsSystemDll() &&
66 StringUtils::CompareNoCase(m_dlls[i]->GetFileName(), sName) == 0)
67 return m_dlls[i];
70 return NULL;
73 LibraryLoader* DllLoaderContainer::GetModule(const HMODULE hModule)
75 for (int i = 0; i < m_iNrOfDlls && m_dlls[i] != NULL; i++)
77 if (m_dlls[i]->GetHModule() == hModule) return m_dlls[i];
79 return NULL;
82 LibraryLoader* DllLoaderContainer::LoadModule(const char* sName, const char* sCurrentDir/*=NULL*/, bool bLoadSymbols/*=false*/)
84 LibraryLoader* pDll=NULL;
86 if (IsSystemDll(sName))
88 pDll = GetModule(sName);
90 else if (sCurrentDir)
92 std::string strPath=sCurrentDir;
93 strPath+=sName;
94 pDll = GetModule(strPath.c_str());
97 if (!pDll)
99 pDll = GetModule(sName);
102 if (!pDll)
104 pDll = FindModule(sName, sCurrentDir, bLoadSymbols);
106 else if (!pDll->IsSystemDll())
108 pDll->IncrRef();
110 #ifdef LOGALL
111 CLog::Log(LOGDEBUG, "Already loaded Dll {} at 0x{:x}", pDll->GetFileName(), pDll);
112 #endif
116 return pDll;
119 LibraryLoader* DllLoaderContainer::FindModule(const char* sName, const char* sCurrentDir, bool bLoadSymbols)
121 if (URIUtils::IsInArchive(sName))
123 CURL url(sName);
124 std::string newName = "special://temp/";
125 newName += url.GetFileName();
126 CFile::Copy(sName, newName);
127 return FindModule(newName.c_str(), sCurrentDir, bLoadSymbols);
130 if (CURL::IsFullPath(sName))
131 { // Has a path, just try to load
132 return LoadDll(sName, bLoadSymbols);
134 #ifdef TARGET_POSIX
135 else if (strcmp(sName, "xbmc.so") == 0)
136 return LoadDll(sName, bLoadSymbols);
137 #endif
138 else if (sCurrentDir)
139 { // in the path of the parent dll?
140 std::string strPath=sCurrentDir;
141 strPath+=sName;
143 if (CFile::Exists(strPath))
144 return LoadDll(strPath.c_str(), bLoadSymbols);
147 // in environment variable?
148 std::vector<std::string> vecEnv;
150 #if defined(TARGET_ANDROID)
151 std::string systemLibs = getenv("KODI_ANDROID_SYSTEM_LIBS");
152 vecEnv = StringUtils::Split(systemLibs, ':');
153 std::string localLibs = getenv("KODI_ANDROID_LIBS");
154 vecEnv.insert(vecEnv.begin(),localLibs);
155 #else
156 vecEnv = StringUtils::Split(ENV_PATH, ';');
157 #endif
158 LibraryLoader* pDll = NULL;
160 for (std::vector<std::string>::const_iterator i = vecEnv.begin(); i != vecEnv.end(); ++i)
162 std::string strPath = *i;
163 URIUtils::AddSlashAtEnd(strPath);
165 #ifdef LOGALL
166 CLog::Log(LOGDEBUG, "Searching for the dll {} in directory {}", sName, strPath);
167 #endif
169 strPath+=sName;
171 // Have we already loaded this dll
172 if ((pDll = GetModule(strPath.c_str())) != NULL)
173 return pDll;
175 if (CFile::Exists(strPath))
176 return LoadDll(strPath.c_str(), bLoadSymbols);
179 // can't find it in any of our paths - could be a system dll
180 if ((pDll = LoadDll(sName, bLoadSymbols)) != NULL)
181 return pDll;
183 CLog::Log(LOGDEBUG, "Dll {} was not found in path", sName);
184 return NULL;
187 void DllLoaderContainer::ReleaseModule(LibraryLoader*& pDll)
189 if (!pDll)
190 return;
191 if (pDll->IsSystemDll())
193 CLog::Log(LOGFATAL, "{} is a system dll and should never be released", pDll->GetName());
194 return;
197 int iRefCount=pDll->DecrRef();
198 if (iRefCount==0)
201 #ifdef LOGALL
202 CLog::Log(LOGDEBUG, "Releasing Dll {}", pDll->GetFileName());
203 #endif
205 if (!pDll->HasSymbols())
207 pDll->Unload();
208 delete pDll;
209 pDll=NULL;
211 else
212 CLog::Log(LOGINFO, "{} has symbols loaded and can never be unloaded", pDll->GetName());
214 #ifdef LOGALL
215 else
217 CLog::Log(LOGDEBUG, "Dll {} is still referenced with a count of {}", pDll->GetFileName(),
218 iRefCount);
220 #endif
223 LibraryLoader* DllLoaderContainer::LoadDll(const char* sName, bool bLoadSymbols)
226 #ifdef LOGALL
227 CLog::Log(LOGDEBUG, "Loading dll {}", sName);
228 #endif
230 LibraryLoader* pLoader;
231 #ifdef TARGET_POSIX
232 pLoader = new SoLoader(sName, bLoadSymbols);
233 #elif defined(TARGET_WINDOWS)
234 pLoader = new Win32DllLoader(sName, false);
235 #endif
237 if (!pLoader)
239 CLog::Log(LOGERROR, "Unable to create dll {}", sName);
240 return NULL;
243 if (!pLoader->Load())
245 delete pLoader;
246 return NULL;
249 return pLoader;
252 bool DllLoaderContainer::IsSystemDll(const char* sName)
254 for (int i = 0; i < m_iNrOfDlls && m_dlls[i] != NULL; i++)
256 if (m_dlls[i]->IsSystemDll() && StringUtils::CompareNoCase(m_dlls[i]->GetName(), sName) == 0)
257 return true;
260 return false;
263 void DllLoaderContainer::RegisterDll(LibraryLoader* pDll)
265 for (LibraryLoader*& dll : m_dlls)
267 if (dll == NULL)
269 dll = pDll;
270 m_iNrOfDlls++;
271 break;
276 void DllLoaderContainer::UnRegisterDll(LibraryLoader* pDll)
278 if (pDll)
280 if (pDll->IsSystemDll())
282 CLog::Log(LOGFATAL, "{} is a system dll and should never be removed", pDll->GetName());
284 else
286 // remove from the list
287 bool bRemoved = false;
288 for (int i = 0; i < m_iNrOfDlls && m_dlls[i]; i++)
290 if (m_dlls[i] == pDll) bRemoved = true;
291 if (bRemoved && i + 1 < m_iNrOfDlls)
293 m_dlls[i] = m_dlls[i + 1];
296 if (bRemoved)
298 m_iNrOfDlls--;
299 m_dlls[m_iNrOfDlls] = NULL;