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

Generated on Tue Jul 12 2016 by doxygen.
Contact: chw@ch-werner.de