Changelog update
[public/netxms.git] / src / libnetxms / dload.cpp
1 /**
2 ** NetXMS - Network Management System
3 ** Utility Library
4 ** Copyright (C) 2003-2017 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU Lesser General Public License as published
8 ** by the Free Software Foundation; either version 3 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU Lesser General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **
20 ** File: dload.cpp
21 **
22 **/
23
24 #include "libnetxms.h"
25
26 #if defined(_NETWARE)
27 #undef SEVERITY_CRITICAL
28 #include <netware.h>
29 #elif !defined(_WIN32)
30 #ifdef _HPUX
31 // dlfcn.h on HP-UX defines it's own UINT64 which conflicts with our definition
32 #define UINT64 __UINT64
33 #include <dlfcn.h>
34 #undef UINT64
35 #else
36 #include <dlfcn.h>
37 #endif
38 #ifndef RTLD_LOCAL
39 #define RTLD_LOCAL 0
40 #endif
41 #endif
42
43 #ifdef _NETWARE
44
45 /**
46 * Error texts for NetWare LoadModule()
47 */
48 static char *m_pszErrorText[] =
49 {
50 "No error",
51 "File not found",
52 "Error reading file",
53 "File not in NLM format",
54 "Wrong NLM file version",
55 "Reentrant initialization failure",
56 "Cannot load multiple copies",
57 "Operation already in progress",
58 "Not enough memory",
59 "Initialization failure",
60 "Inconsistent file format",
61 "Cannot load module at startup",
62 "Unresolved dependencies",
63 "Unresolved external symbols",
64 "Public symbol already defined",
65 "XDC data error",
66 "Module must be loaded in the kernel",
67 "Module is NIOS compatible only and cannot be loaded on NetWare",
68 "Cannot create specified address space",
69 "Module initialization failed"
70 };
71
72 #endif
73
74 /**
75 * Load DLL/shared library
76 */
77 HMODULE LIBNETXMS_EXPORTABLE DLOpen(const TCHAR *pszLibName, TCHAR *pszErrorText)
78 {
79 HMODULE hModule;
80
81 #if defined(_WIN32)
82 hModule = LoadLibrary(pszLibName);
83 if ((hModule == NULL) && (pszErrorText != NULL))
84 GetSystemErrorText(GetLastError(), pszErrorText, 255);
85 #elif defined(_NETWARE)
86 TCHAR szBuffer[MAX_PATH + 4];
87 int nError;
88
89 _tcslcpy(&szBuffer[4], pszLibName, MAX_PATH);
90 nError = LoadModule(getnetwarelogger(), &szBuffer[4], LO_RETURN_HANDLE);
91 if (nError == 0)
92 {
93 hModule = *((HMODULE *)szBuffer);
94 if (pszErrorText != NULL)
95 *pszErrorText = 0;
96 }
97 else
98 {
99 hModule = NULL;
100 if (pszErrorText != NULL)
101 _tcslcpy(pszErrorText, (nError <= 19) ? m_pszErrorText[nError] : "Unknown error code", 255);
102 }
103 #else /* not _WIN32 and not _NETWARE */
104 #ifdef UNICODE
105 char *mbbuffer = MBStringFromWideString(pszLibName);
106 hModule = dlopen(mbbuffer, RTLD_NOW | RTLD_LOCAL);
107 if ((hModule == NULL) && (pszErrorText != NULL))
108 {
109 WCHAR *wbuffer = WideStringFromMBString(dlerror());
110 _tcslcpy(pszErrorText, wbuffer, 255);
111 free(wbuffer);
112 }
113 free(mbbuffer);
114 #else
115 hModule = dlopen(pszLibName, RTLD_NOW | RTLD_LOCAL);
116 if ((hModule == NULL) && (pszErrorText != NULL))
117 _tcslcpy(pszErrorText, dlerror(), 255);
118 #endif
119 #endif
120 return hModule;
121 }
122
123 /**
124 * Unload DLL/shared library
125 */
126 void LIBNETXMS_EXPORTABLE DLClose(HMODULE hModule)
127 {
128 if (hModule != NULL)
129 {
130 #if defined(_WIN32)
131 FreeLibrary(hModule);
132 #elif defined(_NETWARE)
133 char szName[MAX_PATH], szTemp[1024];
134
135 GetNLMNames(hModule, szName, szTemp);
136 szName[szName[0] + 1] = 0;
137 UnloadModule(getscreenhandle(), &szName[1]);
138 #else
139 dlclose(hModule);
140 #endif
141 }
142 }
143
144 /**
145 * Get symbol address from library
146 */
147 void LIBNETXMS_EXPORTABLE *DLGetSymbolAddr(HMODULE hModule, const char *pszSymbol, TCHAR *pszErrorText)
148 {
149 void *pAddr;
150
151 #if defined(_WIN32)
152 pAddr = (void *)GetProcAddress(hModule, pszSymbol);
153 if ((pAddr == NULL) && (pszErrorText != NULL))
154 GetSystemErrorText(GetLastError(), pszErrorText, 255);
155 #elif defined(_NETWARE)
156 pAddr = ImportPublicObject(hModule, pszSymbol);
157 if (pszErrorText != NULL)
158 *pszErrorText = 0;
159 #else /* _WIN32 */
160 pAddr = dlsym(hModule, pszSymbol);
161 if ((pAddr == NULL) && (pszErrorText != NULL))
162 {
163 #ifdef UNICODE
164 WCHAR *wbuffer = WideStringFromMBString(dlerror());
165 _tcslcpy(pszErrorText, wbuffer, 255);
166 free(wbuffer);
167 #else
168 _tcslcpy(pszErrorText, dlerror(), 255);
169 #endif
170 }
171 #endif
172 return pAddr;
173 }