- Fixed agent crash on NetWare (issue 86)
[public/netxms.git] / src / libnetxms / dload.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Utility Library
4 ** Copyright (C) 2003, 2004, 2005, 2006 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 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 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 ** $module: dload.cpp
21 **
22 **/
23
24 #include "libnetxms.h"
25
26 #if defined(_NETWARE)
27 #include <netware.h>
28 #elif !defined(_WIN32)
29 #include <dlfcn.h>
30 #endif
31
32
33 //
34 // Error texts for NetWare LoadModule()
35 //
36
37 #ifdef _NETWARE
38
39 static char *m_pszErrorText[] =
40 {
41 "No error",
42 "File not found",
43 "Error reading file",
44 "File not in NLM format",
45 "Wrong NLM file version",
46 "Reentrant initialization failure",
47 "Cannot load multiple copies",
48 "Operation already in progress",
49 "Not enough memory",
50 "Initialization failure",
51 "Inconsistent file format",
52 "Cannot load module at startup",
53 "Unresolved dependencies",
54 "Unresolved external symbols",
55 "Public symbol already defined",
56 "XDC data error",
57 "Module must be loaded in the kernel",
58 "Module is NIOS compatible only and cannot be loaded on NetWare",
59 "Cannot create specified address space",
60 "Module initialization failed"
61 };
62
63 #endif
64
65
66 //
67 // Load DLL/shared library
68 //
69
70 HMODULE LIBNETXMS_EXPORTABLE DLOpen(TCHAR *szLibName, TCHAR *pszErrorText)
71 {
72 HMODULE hModule;
73
74 #if defined(_WIN32)
75 hModule = LoadLibrary(szLibName);
76 if (hModule == NULL)
77 GetSystemErrorText(GetLastError(), pszErrorText, 255);
78 #elif defined(_NETWARE)
79 TCHAR szBuffer[MAX_PATH + 4];
80 int nError;
81
82 nx_strncpy(&szBuffer[4], szLibName, MAX_PATH);
83 nError = LoadModule(getnetwarelogger(), &szBuffer[4], LO_RETURN_HANDLE);
84 if (nError == 0)
85 {
86 hModule = *((HMODULE *)szBuffer);
87 *pszErrorText = 0;
88 }
89 else
90 {
91 hModule = NULL;
92 nx_strncpy(pszErrorText, (nError <= 19) ? m_pszErrorText[nError] : "Unknown error code", 255);
93 }
94 #else /* _WIN32 */
95 hModule = dlopen(szLibName, RTLD_NOW | RTLD_GLOBAL);
96 if (hModule == NULL)
97 nx_strncpy(pszErrorText, dlerror(), 255);
98 #endif
99 return hModule;
100 }
101
102
103 //
104 // Unload DLL/shared library
105 //
106
107 void LIBNETXMS_EXPORTABLE DLClose(HMODULE hModule)
108 {
109 if (hModule != NULL)
110 {
111 #if defined(_WIN32)
112 FreeLibrary(hModule);
113 #elif defined(_NETWARE)
114 char szName[MAX_PATH], szTemp[1024];
115
116 GetNLMNames(hModule, szName, szTemp);
117 szName[szName[0] + 1] = 0;
118 UnloadModule(getscreenhandle(), &szName[1]);
119 #else
120 dlclose(hModule);
121 #endif
122 }
123 }
124
125
126 //
127 // Get symbol address from library
128 //
129
130 void LIBNETXMS_EXPORTABLE *DLGetSymbolAddr(HMODULE hModule,
131 TCHAR *pszSymbol,
132 TCHAR *pszErrorText)
133 {
134 void *pAddr;
135
136 #if defined(_WIN32)
137 #if !defined(UNDER_CE) && defined(UNICODE)
138 char szBuffer[256];
139
140 WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,
141 pszSymbol, -1, szBuffer, 256, NULL, NULL);
142 pAddr = GetProcAddress(hModule, szBuffer);
143 #else
144 pAddr = GetProcAddress(hModule, pszSymbol);
145 #endif
146 if (pAddr == NULL)
147 GetSystemErrorText(GetLastError(), pszErrorText, 255);
148 #elif defined(_NETWARE)
149 pAddr = ImportPublicObject(hModule, pszSymbol);
150 *pszErrorText = 0;
151 #else /* _WIN32 */
152 pAddr = dlsym(hModule, pszSymbol);
153 if (pAddr == NULL)
154 nx_strncpy(pszErrorText, dlerror(), 255);
155 #endif
156 return pAddr;
157 }