inst.c
Go to the documentation of this file.
1
14#include <windows.h>
15#include <sql.h>
16#include <sqlext.h>
17#include <odbcinst.h>
18#include <winver.h>
19#include <string.h>
20#include <ctype.h>
21#include <stdio.h>
22
23#ifdef SEEEXT
24#define SEESTR " (SEE)"
25#define SEESTR2 "SEE "
26#else
27#define SEEEXT ""
28#define SEESTR ""
29#define SEESTR2 ""
30#endif
31
32#define NUMDRVS 4
33static char *DriverName[NUMDRVS] = {
34 "SQLite ODBC Driver",
35 "SQLite ODBC (UTF-8) Driver",
36 "SQLite3 ODBC Driver" SEESTR,
37 "SQLite4 ODBC Driver"
38};
39static char *DSName[NUMDRVS] = {
40 "SQLite Datasource",
41 "SQLite UTF-8 Datasource",
42 "SQLite3 " SEESTR2 "Datasource",
43 "SQLite4 Datasource"
44};
45static char *DriverDLL[NUMDRVS] = {
46 "sqliteodbc.dll",
47 "sqliteodbcu.dll",
48 "sqlite3odbc" SEEEXT ".dll",
49 "sqlite4odbc.dll"
50};
51#if defined(WITH_SQLITE_DLLS) && (WITH_SQLITE_DLLS <= 1)
52static char *EngineDLL[NUMDRVS] = {
53 "sqlite.dll",
54 "sqliteu.dll",
55 "sqlite3.dll",
56 "sqlite4.dll"
57};
58#endif
59
60static int quiet = 0;
61static int nosys = 0;
62
69static BOOL
71{
72 WORD err = 1;
73 DWORD code;
74 char errmsg[301];
75 WORD errlen, errmax = sizeof (errmsg) - 1;
76 int rc;
77 BOOL ret = FALSE;
78
79 do {
80 errmsg[0] = '\0';
81 rc = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
82 if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
83 if (!quiet) {
84 MessageBox(NULL, errmsg, name,
85 MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
86 }
87 ret = TRUE;
88 }
89 err++;
90 } while (rc != SQL_NO_DATA);
91 return ret;
92}
93
101static BOOL
102CopyOrDelModules(char *dllname, char *path, BOOL del)
103{
104 char firstpat[MAX_PATH];
105 WIN32_FIND_DATA fdata;
106 HANDLE h;
107 DWORD err;
108
109 if (strncmp(dllname, "sqlite3", 7)) {
110 return TRUE;
111 }
112 firstpat[0] = '\0';
113 if (del) {
114 strcpy(firstpat, path);
115 strcat(firstpat, "\\");
116 }
117 strcat(firstpat, "sqlite3_mod*.dll");
118 h = FindFirstFile(firstpat, &fdata);
119 if (h == INVALID_HANDLE_VALUE) {
120 return TRUE;
121 }
122 do {
123 if (del) {
124 DeleteFile(fdata.cFileName);
125 } else {
126 char buf[1024];
127
128 sprintf(buf, "%s\\%s", path, fdata.cFileName);
129 if (!CopyFile(fdata.cFileName, buf, 0)) {
130 sprintf(buf, "Copy %s to %s failed", fdata.cFileName, path);
131 MessageBox(NULL, buf, "CopyFile",
132 MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
133 FindClose(h);
134 return FALSE;
135 }
136 }
137 } while (FindNextFile(h, &fdata));
138 err = GetLastError();
139 FindClose(h);
140 return err == ERROR_NO_MORE_FILES;
141}
142
152static BOOL
153InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
154{
155 char path[301], driver[300], attr[300], inst[400], inst2[400];
156 WORD pathmax = sizeof (path) - 1, pathlen;
157 DWORD usecnt, mincnt;
158
159 if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
160 char *p;
161
162 sprintf(driver, "%s;Driver=%s;Setup=%s;",
163 drivername, dllname, dllname);
164 p = driver;
165 while (*p) {
166 if (*p == ';') {
167 *p = '\0';
168 }
169 ++p;
170 }
171 usecnt = 0;
172 SQLInstallDriverEx(driver, NULL, path, pathmax, &pathlen,
173 ODBC_INSTALL_INQUIRY, &usecnt);
174 sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
175 drivername, path, dllname, path, dllname);
176 p = driver;
177 while (*p) {
178 if (*p == ';') {
179 *p = '\0';
180 }
181 ++p;
182 }
183 sprintf(inst, "%s\\%s", path, dllname);
184 if (dll2name) {
185 sprintf(inst2, "%s\\%s", path, dll2name);
186 }
187 if (!remove && usecnt > 0) {
188 /* first install try: copy over driver dll, keeping DSNs */
189 if (GetFileAttributes(dllname) != INVALID_FILE_ATTRIBUTES &&
190 CopyFile(dllname, inst, 0) &&
191 CopyOrDelModules(dllname, path, 0)) {
192 if (dll2name != NULL) {
193 CopyFile(dll2name, inst2, 0);
194 }
195 return TRUE;
196 }
197 }
198 mincnt = remove ? 1 : 0;
199 while (usecnt != mincnt) {
200 if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
201 break;
202 }
203 }
204 if (remove) {
205 if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
206 if (GetFileAttributes(dllname) != INVALID_FILE_ATTRIBUTES) {
207 ProcessErrorMessages("SQLRemoveDriver", 0);
208 return FALSE;
209 }
210 ProcessErrorMessages("SQLRemoveDriver", 1);
211 usecnt = 1;
212 }
213 if (!usecnt) {
214 char buf[512];
215
216 DeleteFile(inst);
217 /* but keep inst2 */
218 CopyOrDelModules(dllname, path, 1);
219 if (!quiet) {
220 sprintf(buf, "%s uninstalled.", drivername);
221 MessageBox(NULL, buf, "Info",
222 MB_ICONINFORMATION|MB_OK|MB_TASKMODAL|
223 MB_SETFOREGROUND);
224 }
225 }
226 if (nosys) {
227 goto done;
228 }
229 sprintf(attr, "DSN=%s;Database=", dsname);
230 p = attr;
231 while (*p) {
232 if (*p == ';') {
233 *p = '\0';
234 }
235 ++p;
236 }
237 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
238 goto done;
239 }
240 if (GetFileAttributes(dllname) == INVALID_FILE_ATTRIBUTES) {
241 return FALSE;
242 }
243 if (!CopyFile(dllname, inst, 0)) {
244 char buf[512];
245
246 sprintf(buf, "Copy %s to %s failed", dllname, inst);
247 MessageBox(NULL, buf, "CopyFile",
248 MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
249 return FALSE;
250 }
251 if (dll2name != NULL && !CopyFile(dll2name, inst2, 0)) {
252 char buf[512];
253
254 sprintf(buf, "Copy %s to %s failed", dll2name, inst2);
255 MessageBox(NULL, buf, "CopyFile",
256 MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
257 /* but go on hoping that an SQLite engine is in place */
258 }
259 if (!CopyOrDelModules(dllname, path, 0)) {
260 return FALSE;
261 }
262 if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
263 ODBC_INSTALL_COMPLETE, &usecnt)) {
264 ProcessErrorMessages("SQLInstallDriverEx", 0);
265 return FALSE;
266 }
267 if (nosys) {
268 goto done;
269 }
270 sprintf(attr, "DSN=%s;Database=;", dsname);
271 p = attr;
272 while (*p) {
273 if (*p == ';') {
274 *p = '\0';
275 }
276 ++p;
277 }
278 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
279 if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
280 ProcessErrorMessages("SQLConfigDataSource", 0);
281 return FALSE;
282 }
283 } else {
284 ProcessErrorMessages("SQLInstallDriverManager", 0);
285 return FALSE;
286 }
287done:
288 return TRUE;
289}
290
298int APIENTRY
299WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
300 LPSTR lpszCmdLine, int nCmdShow)
301{
302 char path[300], *p;
303 int i, remove;
304 BOOL ret[NUMDRVS];
305
306 GetModuleFileName(NULL, path, sizeof (path));
307 p = path;
308 while (*p) {
309 *p = tolower(*p);
310 ++p;
311 }
312 p = strrchr(path, '\\');
313 if (p == NULL) {
314 p = path;
315 } else {
316 *p = '\0';
317 ++p;
318 SetCurrentDirectory(path);
319 }
320 remove = strstr(p, "uninst") != NULL;
321 quiet = strstr(p, "instq") != NULL;
322 nosys = strstr(p, "nosys") != NULL;
323 for (i = 0; i < NUMDRVS; i++) {
324#if defined(WITH_SQLITE_DLLS) && (WITH_SQLITE_DLLS <= 1)
325 p = EngineDLL[i];
326#else
327 p = NULL;
328#endif
329 ret[i] = InUn(remove, DriverName[i], DriverDLL[i], p, DSName[i]);
330 }
331 for (i = 1; i < NUMDRVS; i++) {
332 ret[0] = ret[0] || ret[i];
333 }
334 if (!remove && ret[0]) {
335 if (!quiet) {
336 MessageBox(NULL, "SQLite ODBC Driver(s) installed.", "Info",
337 MB_ICONINFORMATION|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
338 }
339 }
340 exit(0);
341}
342
343/*
344 * Local Variables:
345 * mode: c
346 * c-basic-offset: 4
347 * fill-column: 78
348 * tab-width: 8
349 * End:
350 */
#define SEESTR
Definition inst.c:28
#define NUMDRVS
Definition inst.c:32
#define SEESTR2
Definition inst.c:29
static char * DriverName[NUMDRVS]
Definition inst.c:33
static int quiet
Definition inst.c:60
static char * DSName[NUMDRVS]
Definition inst.c:39
static char * DriverDLL[NUMDRVS]
Definition inst.c:45
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
Main function of installer/uninstaller.
Definition inst.c:299
static BOOL ProcessErrorMessages(char *name, int quiet)
Handler for ODBC installation error messages.
Definition inst.c:70
static BOOL CopyOrDelModules(char *dllname, char *path, BOOL del)
Copy or delete SQLite3 module DLLs.
Definition inst.c:102
#define SEEEXT
Definition inst.c:27
static BOOL InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
Driver installer/uninstaller.
Definition inst.c:153
static int nosys
Definition inst.c:61

Generated on Sun Nov 26 2023 by doxygen.
Contact: chw@ch-werner.de