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
33 static char *DriverName[NUMDRVS] = {
34  "SQLite ODBC Driver",
35  "SQLite ODBC (UTF-8) Driver",
36  "SQLite3 ODBC Driver" SEESTR,
37  "SQLite4 ODBC Driver"
38 };
39 static char *DSName[NUMDRVS] = {
40  "SQLite Datasource",
41  "SQLite UTF-8 Datasource",
42  "SQLite3 " SEESTR2 "Datasource",
43  "SQLite4 Datasource"
44 };
45 static char *DriverDLL[NUMDRVS] = {
46  "sqliteodbc.dll",
47  "sqliteodbcu.dll",
48  "sqlite3odbc" SEEEXT ".dll",
49  "sqlite4odbc.dll"
50 };
51 #ifdef WITH_SQLITE_DLLS
52 static char *EngineDLL[NUMDRVS] = {
53  "sqlite.dll",
54  "sqliteu.dll",
55  "sqlite3.dll",
56  "sqlite4.dll"
57 };
58 #endif
59 
60 static int quiet = 0;
61 static int nosys = 0;
62 
69 static BOOL
70 ProcessErrorMessages(char *name, int quiet)
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 
101 static BOOL
102 CopyOrDelModules(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 
152 static BOOL
153 InUn(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  }
287 done:
288  return TRUE;
289 }
290 
298 int APIENTRY
299 WinMain(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 #ifdef WITH_SQLITE_DLLS
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 Mon Aug 17 2020 by doxygen.
Contact: chw@ch-werner.de