Added database driver API version checking
[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 #ifndef RTLD_GLOBAL
31 #define RTLD_GLOBAL 0
32 #endif
33 #endif
34
35
36 //
37 // Error texts for NetWare LoadModule()
38 //
39
40 #ifdef _NETWARE
41
42 static char *m_pszErrorText[] =
43 {
44 "No error",
45 "File not found",
46 "Error reading file",
47 "File not in NLM format",
48 "Wrong NLM file version",
49 "Reentrant initialization failure",
50 "Cannot load multiple copies",
51 "Operation already in progress",
52 "Not enough memory",
53 "Initialization failure",
54 "Inconsistent file format",
55 "Cannot load module at startup",
56 "Unresolved dependencies",
57 "Unresolved external symbols",
58 "Public symbol already defined",
59 "XDC data error",
60 "Module must be loaded in the kernel",
61 "Module is NIOS compatible only and cannot be loaded on NetWare",
62 "Cannot create specified address space",
63 "Module initialization failed"
64 };
65
66 #endif
67
68
69 //
70 // Load DLL/shared library
71 //
72
73 HMODULE LIBNETXMS_EXPORTABLE DLOpen(TCHAR *szLibName, TCHAR *pszErrorText)
74 {
75 HMODULE hModule;
76
77 #if defined(_WIN32)
78 hModule = LoadLibrary(szLibName);
79 if (hModule == NULL)
80 GetSystemErrorText(GetLastError(), pszErrorText, 255);
81 #elif defined(_NETWARE)
82 TCHAR szBuffer[MAX_PATH + 4];
83 int nError;
84
85 nx_strncpy(&szBuffer[4], szLibName, MAX_PATH);
86 nError = LoadModule(getnetwarelogger(), &szBuffer[4], LO_RETURN_HANDLE);
87 if (nError == 0)
88 {
89 hModule = *((HMODULE *)szBuffer);
90 *pszErrorText = 0;
91 }
92 else
93 {
94 hModule = NULL;
95 nx_strncpy(pszErrorText, (nError <= 19) ? m_pszErrorText[nError] : "Unknown error code", 255);
96 }
97 #else /* _WIN32 */
98 hModule = dlopen(szLibName, RTLD_NOW | RTLD_GLOBAL);
99 if (hModule == NULL)
100 nx_strncpy(pszErrorText, dlerror(), 255);
101 #endif
102 return hModule;
103 }
104
105
106 //
107 // Unload DLL/shared library
108 //
109
110 void LIBNETXMS_EXPORTABLE DLClose(HMODULE hModule)
111 {
112 if (hModule != NULL)
113 {
114 #if defined(_WIN32)
115 FreeLibrary(hModule);
116 #elif defined(_NETWARE)
117 char szName[MAX_PATH], szTemp[1024];
118
119 GetNLMNames(hModule, szName, szTemp);
120 szName[szName[0] + 1] = 0;
121 UnloadModule(getscreenhandle(), &szName[1]);
122 #else
123 dlclose(hModule);
124 #endif
125 }
126 }
127
128
129 //
130 // Get symbol address from library
131 //
132
133 void LIBNETXMS_EXPORTABLE *DLGetSymbolAddr(HMODULE hModule,
134 TCHAR *pszSymbol,
135 TCHAR *pszErrorText)
136 {
137 void *pAddr;
138
139 #if defined(_WIN32)
140 #if !defined(UNDER_CE) && defined(UNICODE)
141 char szBuffer[256];
142
143 WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,
144 pszSymbol, -1, szBuffer, 256, NULL, NULL);
145 pAddr = GetProcAddress(hModule, szBuffer);
146 #else
147 pAddr = GetProcAddress(hModule, pszSymbol);
148 #endif
149 if ((pAddr == NULL) && (pszErrorText != NULL))
150 GetSystemErrorText(GetLastError(), pszErrorText, 255);
151 #elif defined(_NETWARE)
152 pAddr = ImportPublicObject(hModule, pszSymbol);
153 if (pszErrorText != NULL)
154 *pszErrorText = 0;
155 #else /* _WIN32 */
156 pAddr = dlsym(hModule, pszSymbol);
157 if ((pAddr == NULL) && (pszErrorText != NULL))
158 nx_strncpy(pszErrorText, dlerror(), 255);
159 #endif
160 return pAddr;
161 }