• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2011 The Android Open Source Project
2 **
3 ** This software is licensed under the terms of the GNU General Public
4 ** License version 2, as published by the Free Software Foundation, and
5 ** may be copied, distributed, and modified under those terms.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 ** GNU General Public License for more details.
11 */
12 #include <android/utils/dll.h>
13 #include <android/utils/system.h>
14 #include <android/utils/path.h>
15 
16 #include <stdlib.h>
17 
18 /* Utility function, append one string to another, caller must free result */
19 static char*
append_string(const char * str1,const char * str2)20 append_string( const char* str1, const char* str2 )
21 {
22     int   len1   = strlen(str1);
23     int   len2   = strlen(str2);
24     char* result = malloc(len1+len2+1);
25 
26     if (result != NULL) {
27         memcpy(result, str1, len1);
28         memcpy(result + len1, str2, len2);
29         result[len1+len2] = '\0';
30     }
31     return result;
32 }
33 
34 #ifdef _WIN32
35 
36 #include <windows.h>
37 
38 /* This function is used to revert all forward slashes (/) in a path
39  * string into unquoted backwards one (\). This is necessary because
40  * LoadLibrary() and AddDllDirectory() do not support forward slashes.
41  *
42  * Caller must free the result string
43  */
44 static char*
reverse_slashes(const char * path)45 reverse_slashes( const char* path )
46 {
47     int   len    = strlen(path);
48     char* result = malloc(len+1);
49     int   nn;
50 
51     for (nn = 0; nn < len; nn++) {
52         int ch = path[nn];
53         if (ch == '/') {
54             ch = '\\';
55         }
56         result[nn] = (char)ch;
57     }
58     result[nn] = '\0';
59 
60     return result;
61 }
62 
63 ADynamicLibrary*
adynamicLibrary_open(const char * libraryName,char ** pError)64 adynamicLibrary_open( const char*  libraryName,
65                       char**       pError)
66 {
67     char*  libName = (char*) libraryName;
68     void*  result;
69 
70     /* Append a .dll to the library name if it doesn't have an extension */
71     if (strchr(libraryName,'.') == NULL) {
72         libName = append_string(libraryName, ".dll");
73     }
74 
75     /* Now do our magic */
76     *pError = NULL;
77     result = (ADynamicLibrary*) LoadLibrary( libName );
78     if (result == NULL) {
79         *pError = ASTRDUP("Could not load DLL!");
80     }
81 
82     /* Free the library name if we modified it */
83     if (libName != libraryName) {
84         free(libName);
85     }
86 
87     return (ADynamicLibrary*) result;
88 }
89 
90 void*
adynamicLibrary_findSymbol(ADynamicLibrary * lib,const char * symbolName,char ** pError)91 adynamicLibrary_findSymbol( ADynamicLibrary*  lib,
92                             const char*       symbolName,
93                             char**            pError)
94 {
95     void* result;
96 
97     *pError = NULL;
98 
99     if (lib == NULL) {
100         *pError = strdup("NULL library pointer");
101         return NULL;
102     }
103     if (symbolName == NULL || symbolName[0] == '\0') {
104         *pError = strdup("NULL or empty symbolName");
105         return NULL;
106     }
107     result = GetProcAddress( (HMODULE)lib, symbolName );
108     if (result == NULL) {
109         *pError = ASTRDUP("Could not find symbol");
110     }
111     return result;
112 }
113 
114 /* Close/unload a given dynamic library */
115 void
adynamicLibrary_close(ADynamicLibrary * lib)116 adynamicLibrary_close( ADynamicLibrary*  lib )
117 {
118     if (lib != NULL) {
119         FreeLibrary( (HMODULE)lib );
120     }
121 }
122 
123 #else /* !_WIN32 */
124 
125 #include <dlfcn.h>
126 #include <stdlib.h>
127 
128 ADynamicLibrary*
adynamicLibrary_open(const char * libraryName,char ** pError)129 adynamicLibrary_open( const char*  libraryName,
130                       char**       pError)
131 {
132     char*  libName = (char*) libraryName;
133     void*  result;
134 
135 #ifdef __APPLE__
136 #  define SO_EXTENSION ".dylib"
137 #else
138 #  define SO_EXTENSION ".so"
139 #endif
140 
141     /* Append a .so to the library name if it doesn't have an extension */
142     if (strchr(libraryName,'.') == NULL) {
143         libName = append_string(libraryName, SO_EXTENSION);
144     }
145 
146     /* Now do our magic */
147     *pError = NULL;
148     result  = dlopen( libName, RTLD_LAZY );
149     if (result == NULL) {
150         *pError = strdup(dlerror());
151     }
152 
153     /* Free the library name if we modified it */
154     if (libName != (char*)libraryName) {
155         free(libName);
156     }
157 
158     return (ADynamicLibrary*) result;
159 }
160 
161 void*
adynamicLibrary_findSymbol(ADynamicLibrary * lib,const char * symbolName,char ** pError)162 adynamicLibrary_findSymbol( ADynamicLibrary*  lib,
163                             const char*       symbolName,
164                             char**            pError)
165 {
166     void* result;
167 
168     *pError = NULL;
169 
170     if (lib == NULL) {
171         *pError = strdup("NULL library pointer");
172         return NULL;
173     }
174     if (symbolName == NULL || symbolName[0] == '\0') {
175         *pError = strdup("NULL or empty symbolName");
176         return NULL;
177     }
178     result = dlsym(lib, symbolName);
179     if (result == NULL) {
180         *pError = strdup(dlerror());
181     }
182     return result;
183 }
184 
185 /* Close/unload a given dynamic library */
186 void
adynamicLibrary_close(ADynamicLibrary * lib)187 adynamicLibrary_close( ADynamicLibrary*  lib )
188 {
189     if (lib != NULL) {
190         dlclose(lib);
191     }
192 }
193 
194 #endif /* !_WIN32 */
195