Mercurial > hg > vamp-plugin-load-checker
comparison src/helper.cpp @ 38:a43d7a2867d2
Tidy up error handling, especially on Windows
author | Chris Cannam |
---|---|
date | Tue, 28 Aug 2018 14:33:41 +0100 |
parents | 146d42909e71 |
children | 40c6936c2fc9 |
comparison
equal
deleted
inserted
replaced
37:3ccc384c0161 | 38:a43d7a2867d2 |
---|---|
67 static const char programName[] = "vamp-plugin-load-checker"; | 67 static const char programName[] = "vamp-plugin-load-checker"; |
68 | 68 |
69 #ifdef _WIN32 | 69 #ifdef _WIN32 |
70 #include <windows.h> | 70 #include <windows.h> |
71 #include <process.h> | 71 #include <process.h> |
72 #endif | |
73 | |
72 #include <string> | 74 #include <string> |
73 #ifdef UNICODE | 75 #include <iostream> |
76 | |
77 #ifdef _WIN32 | |
78 #ifndef UNICODE | |
79 #error "This must be compiled with UNICODE defined" | |
80 #endif | |
74 static std::string lastLibraryName = ""; | 81 static std::string lastLibraryName = ""; |
75 static HMODULE LoadLibraryUTF8(std::string name) { | 82 static HMODULE LoadLibraryUTF8(std::string name) { |
76 lastLibraryName = name; | 83 lastLibraryName = name; |
77 int n = name.size(); | 84 int n = name.size(); |
78 int wn = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), n, 0, 0); | 85 int wn = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), n, 0, 0); |
82 HMODULE h = LoadLibraryW(wname); | 89 HMODULE h = LoadLibraryW(wname); |
83 delete[] wname; | 90 delete[] wname; |
84 return h; | 91 return h; |
85 } | 92 } |
86 static std::string GetErrorText() { | 93 static std::string GetErrorText() { |
94 DWORD err = GetLastError(); | |
87 wchar_t *buffer; | 95 wchar_t *buffer; |
88 DWORD err = GetLastError(); | 96 FormatMessageW( |
89 FormatMessage( | |
90 FORMAT_MESSAGE_ALLOCATE_BUFFER | | 97 FORMAT_MESSAGE_ALLOCATE_BUFFER | |
91 FORMAT_MESSAGE_FROM_SYSTEM | | 98 FORMAT_MESSAGE_FROM_SYSTEM | |
92 FORMAT_MESSAGE_IGNORE_INSERTS, | 99 FORMAT_MESSAGE_IGNORE_INSERTS, |
93 NULL, | 100 NULL, |
94 err, | 101 err, |
95 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | 102 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
96 (LPTSTR) &buffer, | 103 (LPWSTR) &buffer, |
97 0, NULL ); | 104 0, NULL ); |
98 int wn = wcslen(buffer); | 105 int wn = wcslen(buffer); |
99 int n = WideCharToMultiByte(CP_UTF8, 0, buffer, wn, 0, 0, 0, 0); | 106 int n = WideCharToMultiByte(CP_UTF8, 0, buffer, wn, 0, 0, 0, 0); |
100 if (n < 0) { | 107 if (n < 0) { |
101 LocalFree(&buffer); | 108 LocalFree(&buffer); |
118 s.replace(pos, 2, lastLibraryName); | 125 s.replace(pos, 2, lastLibraryName); |
119 } | 126 } |
120 return s; | 127 return s; |
121 } | 128 } |
122 #define DLOPEN(a,b) LoadLibraryUTF8(a) | 129 #define DLOPEN(a,b) LoadLibraryUTF8(a) |
123 #else | |
124 #define DLOPEN(a,b) LoadLibrary((a).c_str()) | |
125 #define GetErrorText() "" | |
126 #endif | |
127 #define DLSYM(a,b) (void *)GetProcAddress((HINSTANCE)(a),(b).c_str()) | 130 #define DLSYM(a,b) (void *)GetProcAddress((HINSTANCE)(a),(b).c_str()) |
128 #define DLCLOSE(a) (!FreeLibrary((HINSTANCE)(a))) | 131 #define DLCLOSE(a) (!FreeLibrary((HINSTANCE)(a))) |
129 #define DLERROR() (GetErrorText()) | 132 #define DLERROR() (GetErrorText()) |
130 #else | 133 #else |
131 #include <dlfcn.h> | 134 #include <dlfcn.h> |
133 #define DLSYM(a,b) dlsym((a),(b).c_str()) | 136 #define DLSYM(a,b) dlsym((a),(b).c_str()) |
134 #define DLCLOSE(a) dlclose((a)) | 137 #define DLCLOSE(a) dlclose((a)) |
135 #define DLERROR() dlerror() | 138 #define DLERROR() dlerror() |
136 #endif | 139 #endif |
137 | 140 |
138 #include <string> | |
139 #include <iostream> | |
140 | |
141 //#include <unistd.h> | 141 //#include <unistd.h> |
142 | 142 |
143 using namespace std; | 143 using namespace std; |
144 | 144 |
145 string error() | 145 string error() |
154 typedef const void *(*DFn)(unsigned long); | 154 typedef const void *(*DFn)(unsigned long); |
155 DFn fn = DFn(f); | 155 DFn fn = DFn(f); |
156 unsigned long index = 0; | 156 unsigned long index = 0; |
157 while (fn(index)) ++index; | 157 while (fn(index)) ++index; |
158 if (index == 0) return "Library contains no plugins"; | 158 if (index == 0) return "Library contains no plugins"; |
159 // else cerr << "Library contains " << index << " plugin(s)" << endl; | |
160 return ""; | 159 return ""; |
161 } | 160 } |
162 | 161 |
163 string checkVampDescriptorFn(void *f) | 162 string checkVampDescriptorFn(void *f) |
164 { | 163 { |
165 typedef const void *(*DFn)(unsigned int, unsigned int); | 164 typedef const void *(*DFn)(unsigned int, unsigned int); |
166 DFn fn = DFn(f); | 165 DFn fn = DFn(f); |
167 unsigned int index = 0; | 166 unsigned int index = 0; |
168 while (fn(2, index)) ++index; | 167 while (fn(2, index)) ++index; |
169 if (index == 0) return "Library contains no plugins"; | 168 if (index == 0) return "Library contains no plugins"; |
170 // else cerr << "Library contains " << index << " plugin(s)" << endl; | |
171 return ""; | 169 return ""; |
172 } | 170 } |
173 | 171 |
174 string check(string soname, string descriptor) | 172 string check(string soname, string descriptor) |
175 { | 173 { |
176 void *handle = DLOPEN(soname, RTLD_NOW | RTLD_LOCAL); | 174 void *handle = DLOPEN(soname, RTLD_NOW | RTLD_LOCAL); |
177 if (!handle) { | 175 if (!handle) { |
178 return "Unable to open plugin library: " + error(); | 176 return "Unable to open plugin library: " + error(); |
179 } | 177 } |
180 | 178 |
179 string msg = ""; | |
180 | |
181 void *fn = DLSYM(handle, descriptor); | 181 void *fn = DLSYM(handle, descriptor); |
182 if (!fn) { | 182 if (!fn) { |
183 return "Failed to find plugin descriptor " + descriptor + | 183 msg = "Failed to find plugin descriptor " + descriptor + |
184 " in library: " + error(); | 184 " in library: " + error(); |
185 } | 185 } else if (descriptor == "ladspa_descriptor") { |
186 | 186 msg = checkLADSPAStyleDescriptorFn(fn); |
187 if (descriptor == "ladspa_descriptor") { | |
188 return checkLADSPAStyleDescriptorFn(fn); | |
189 } else if (descriptor == "dssi_descriptor") { | 187 } else if (descriptor == "dssi_descriptor") { |
190 return checkLADSPAStyleDescriptorFn(fn); | 188 msg = checkLADSPAStyleDescriptorFn(fn); |
191 } else if (descriptor == "vampGetPluginDescriptor") { | 189 } else if (descriptor == "vampGetPluginDescriptor") { |
192 return checkVampDescriptorFn(fn); | 190 msg = checkVampDescriptorFn(fn); |
193 } else { | 191 } else { |
194 cerr << "Note: no descriptor logic known for descriptor function \"" | 192 cerr << "Note: no descriptor logic known for descriptor function \"" |
195 << descriptor << "\"; not actually calling it" << endl; | 193 << descriptor << "\"; not actually calling it" << endl; |
196 } | 194 } |
197 | 195 |
198 return ""; | 196 DLCLOSE(handle); |
197 | |
198 return msg; | |
199 } | 199 } |
200 | 200 |
201 int main(int argc, char **argv) | 201 int main(int argc, char **argv) |
202 { | 202 { |
203 bool allGood = true; | 203 bool allGood = true; |