Mercurial > hg > vamp-plugin-load-checker
comparison src/helper.cpp @ 42:49946b02414e errorcode
Further error checking - distinguish between library and dependency absent
author | Chris Cannam |
---|---|
date | Thu, 30 Aug 2018 12:32:55 +0100 |
parents | 40c6936c2fc9 |
children | d7ec0b2a8802 |
comparison
equal
deleted
inserted
replaced
41:7f5cf0fed473 | 42:49946b02414e |
---|---|
91 #error "This must be compiled with UNICODE defined" | 91 #error "This must be compiled with UNICODE defined" |
92 #endif | 92 #endif |
93 | 93 |
94 static std::string lastLibraryName = ""; | 94 static std::string lastLibraryName = ""; |
95 | 95 |
96 static HMODULE LoadLibraryUTF8(std::string name) { | 96 static HMODULE loadLibraryUTF8(std::string name) { |
97 lastLibraryName = name; | 97 lastLibraryName = name; |
98 int n = name.size(); | 98 int n = name.size(); |
99 int wn = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), n, 0, 0); | 99 int wn = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), n, 0, 0); |
100 wchar_t *wname = new wchar_t[wn+1]; | 100 wchar_t *wname = new wchar_t[wn+1]; |
101 wn = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), n, wname, wn); | 101 wn = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), n, wname, wn); |
103 HMODULE h = LoadLibraryW(wname); | 103 HMODULE h = LoadLibraryW(wname); |
104 delete[] wname; | 104 delete[] wname; |
105 return h; | 105 return h; |
106 } | 106 } |
107 | 107 |
108 static std::string GetErrorText() { | 108 static std::string getErrorText() { |
109 DWORD err = GetLastError(); | 109 DWORD err = GetLastError(); |
110 wchar_t *buffer; | 110 wchar_t *buffer = 0; |
111 FormatMessageW( | 111 FormatMessageW( |
112 FORMAT_MESSAGE_ALLOCATE_BUFFER | | 112 FORMAT_MESSAGE_ALLOCATE_BUFFER | |
113 FORMAT_MESSAGE_FROM_SYSTEM | | 113 FORMAT_MESSAGE_FROM_SYSTEM | |
114 FORMAT_MESSAGE_IGNORE_INSERTS, | 114 FORMAT_MESSAGE_IGNORE_INSERTS, |
115 NULL, | 115 NULL, |
116 err, | 116 err, |
117 MAKELANGID(LANG_USER_DEFAULT, SUBLANG_USER_DEFAULT), | 117 // the correct way to specify the user's default language, |
118 // according to all resources I could find: | |
119 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
118 (LPWSTR) &buffer, | 120 (LPWSTR) &buffer, |
119 0, NULL ); | 121 0, NULL ); |
122 if (!buffer) { | |
123 return "Unable to format error string (internal error)"; | |
124 } | |
120 int wn = wcslen(buffer); | 125 int wn = wcslen(buffer); |
121 int n = WideCharToMultiByte(CP_UTF8, 0, buffer, wn, 0, 0, 0, 0); | 126 int n = WideCharToMultiByte(CP_UTF8, 0, buffer, wn, 0, 0, 0, 0); |
122 if (n < 0) { | 127 if (n < 0) { |
123 LocalFree(&buffer); | 128 LocalFree(&buffer); |
124 return "Unable to convert error string (internal error)"; | 129 return "Unable to convert error string (internal error)"; |
127 (void)WideCharToMultiByte(CP_UTF8, 0, buffer, wn, text, n, 0, 0); | 132 (void)WideCharToMultiByte(CP_UTF8, 0, buffer, wn, text, n, 0, 0); |
128 text[n] = '\0'; | 133 text[n] = '\0'; |
129 std::string s(text); | 134 std::string s(text); |
130 LocalFree(&buffer); | 135 LocalFree(&buffer); |
131 delete[] text; | 136 delete[] text; |
137 if (s == "") { | |
138 return s; | |
139 } | |
132 for (int i = s.size(); i > 0; ) { | 140 for (int i = s.size(); i > 0; ) { |
133 --i; | 141 --i; |
134 if (s[i] == '\n' || s[i] == '\r') { | 142 if (s[i] == '\n' || s[i] == '\r') { |
135 s.erase(i, 1); | 143 s.erase(i, 1); |
136 } | 144 } |
140 s.replace(pos, 2, lastLibraryName); | 148 s.replace(pos, 2, lastLibraryName); |
141 } | 149 } |
142 return s; | 150 return s; |
143 } | 151 } |
144 | 152 |
145 #define DLOPEN(a,b) LoadLibraryUTF8(a) | 153 #define DLOPEN(a,b) loadLibraryUTF8(a) |
146 #define DLSYM(a,b) (void *)GetProcAddress((HINSTANCE)(a),(b).c_str()) | 154 #define DLSYM(a,b) (void *)GetProcAddress((HINSTANCE)(a),(b).c_str()) |
147 #define DLCLOSE(a) (!FreeLibrary((HINSTANCE)(a))) | 155 #define DLCLOSE(a) (!FreeLibrary((HINSTANCE)(a))) |
148 #define DLERROR() (GetErrorText()) | 156 #define DLERROR() (getErrorText()) |
157 | |
158 static bool libraryExists(std::string name) { | |
159 if (name == "") return false; | |
160 int n = name.size(); | |
161 int wn = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), n, 0, 0); | |
162 wchar_t *wname = new wchar_t[wn+1]; | |
163 wn = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), n, wname, wn); | |
164 wname[wn] = L'\0'; | |
165 FILE *f = _wfopen(wname, L"rb"); | |
166 delete[] wname; | |
167 if (f) { | |
168 fclose(f); | |
169 return true; | |
170 } else { | |
171 return false; | |
172 } | |
173 } | |
149 | 174 |
150 #else | 175 #else |
151 | 176 |
152 #include <dlfcn.h> | 177 #include <dlfcn.h> |
153 #define DLOPEN(a,b) dlopen((a).c_str(),(b)) | 178 #define DLOPEN(a,b) dlopen((a).c_str(),(b)) |
154 #define DLSYM(a,b) dlsym((a),(b).c_str()) | 179 #define DLSYM(a,b) dlsym((a),(b).c_str()) |
155 #define DLCLOSE(a) dlclose((a)) | 180 #define DLCLOSE(a) dlclose((a)) |
156 #define DLERROR() dlerror() | 181 #define DLERROR() dlerror() |
182 | |
183 static bool libraryExists(std::string name) { | |
184 if (name == "") return false; | |
185 FILE *f = fopen(name.c_str(), "r"); | |
186 if (f) { | |
187 fclose(f); | |
188 return true; | |
189 } else { | |
190 return false; | |
191 } | |
192 } | |
157 | 193 |
158 #endif | 194 #endif |
159 | 195 |
160 //#include <unistd.h> | 196 //#include <unistd.h> |
161 | 197 |
200 #ifdef _WIN32 | 236 #ifdef _WIN32 |
201 DWORD err = GetLastError(); | 237 DWORD err = GetLastError(); |
202 if (err == ERROR_BAD_EXE_FORMAT) { | 238 if (err == ERROR_BAD_EXE_FORMAT) { |
203 code = PluginCheckCode::FAIL_WRONG_ARCHITECTURE; | 239 code = PluginCheckCode::FAIL_WRONG_ARCHITECTURE; |
204 } else if (err == ERROR_MOD_NOT_FOUND) { | 240 } else if (err == ERROR_MOD_NOT_FOUND) { |
205 code = PluginCheckCode::FAIL_DEPENDENCY_MISSING; | 241 if (libraryExists(soname)) { |
242 code = PluginCheckCode::FAIL_DEPENDENCY_MISSING; | |
243 } else { | |
244 code = PluginCheckCode::FAIL_LIBRARY_NOT_FOUND; | |
245 } | |
246 } | |
247 #else | |
248 if (!libraryExists(soname)) { | |
249 code = PluginCheckCode::FAIL_LIBRARY_NOT_FOUND; | |
206 } | 250 } |
207 #endif | 251 #endif |
208 return { code, message }; | 252 return { code, message }; |
209 } | 253 } |
210 | 254 |