Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

inst.c

Go to the documentation of this file.
00001 
00014 #include <windows.h>
00015 #include <sql.h>
00016 #include <sqlext.h>
00017 #include <odbcinst.h>
00018 #include <winver.h>
00019 #include <string.h>
00020 #include <ctype.h>
00021 #include <stdio.h>
00022 
00023 #ifdef SEEEXT
00024 #define SEESTR " (SEE)"
00025 #define SEESTR2 "SEE "
00026 #else
00027 #define SEEEXT ""
00028 #define SEESTR ""
00029 #define SEESTR2 ""
00030 #endif
00031 
00032 #define NUMDRVS 4
00033 static char *DriverName[NUMDRVS] = {
00034     "SQLite ODBC Driver",
00035     "SQLite ODBC (UTF-8) Driver",
00036     "SQLite3 ODBC Driver" SEESTR,
00037     "SQLite4 ODBC Driver"
00038 };
00039 static char *DSName[NUMDRVS] = {
00040     "SQLite Datasource",
00041     "SQLite UTF-8 Datasource",
00042     "SQLite3 " SEESTR2 "Datasource",
00043     "SQLite4 Datasource"
00044 };
00045 static char *DriverDLL[NUMDRVS] = {
00046     "sqliteodbc.dll",
00047     "sqliteodbcu.dll",
00048     "sqlite3odbc" SEEEXT ".dll",
00049     "sqlite4odbc.dll"
00050 };
00051 #ifdef WITH_SQLITE_DLLS
00052 static char *EngineDLL[NUMDRVS] = {
00053     "sqlite.dll",
00054     "sqliteu.dll",
00055     "sqlite3.dll",
00056     "sqlite4.dll"
00057 };
00058 #endif
00059 
00060 static int quiet = 0;
00061 static int nosys = 0;
00062 
00069 static BOOL
00070 ProcessErrorMessages(char *name, int quiet)
00071 {
00072     WORD err = 1;
00073     DWORD code;
00074     char errmsg[301];
00075     WORD errlen, errmax = sizeof (errmsg) - 1;
00076     int rc;
00077     BOOL ret = FALSE;
00078 
00079     do {
00080         errmsg[0] = '\0';
00081         rc = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
00082         if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
00083             if (!quiet) {
00084                 MessageBox(NULL, errmsg, name,
00085                            MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
00086             }
00087             ret = TRUE;
00088         }
00089         err++;
00090     } while (rc != SQL_NO_DATA);
00091     return ret;
00092 }
00093 
00101 static BOOL
00102 CopyOrDelModules(char *dllname, char *path, BOOL del)
00103 {
00104     char firstpat[MAX_PATH];
00105     WIN32_FIND_DATA fdata;
00106     HANDLE h;
00107     DWORD err;
00108 
00109     if (strncmp(dllname, "sqlite3", 7)) {
00110         return TRUE;
00111     }
00112     firstpat[0] = '\0';
00113     if (del) {
00114         strcpy(firstpat, path);
00115         strcat(firstpat, "\\");
00116     }
00117     strcat(firstpat, "sqlite3_mod*.dll");
00118     h = FindFirstFile(firstpat, &fdata);
00119     if (h == INVALID_HANDLE_VALUE) {
00120         return TRUE;
00121     }
00122     do {
00123         if (del) {
00124             DeleteFile(fdata.cFileName);
00125         } else {
00126             char buf[1024];
00127 
00128             sprintf(buf, "%s\\%s", path, fdata.cFileName);
00129             if (!CopyFile(fdata.cFileName, buf, 0)) {
00130                 sprintf(buf, "Copy %s to %s failed", fdata.cFileName, path);
00131                 MessageBox(NULL, buf, "CopyFile",
00132                            MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
00133                 FindClose(h);
00134                 return FALSE;
00135             }
00136         }
00137     } while (FindNextFile(h, &fdata));
00138     err = GetLastError();
00139     FindClose(h);
00140     return err == ERROR_NO_MORE_FILES;
00141 }
00142 
00152 static BOOL
00153 InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
00154 {
00155     char path[301], driver[300], attr[300], inst[400], inst2[400];
00156     WORD pathmax = sizeof (path) - 1, pathlen;
00157     DWORD usecnt, mincnt;
00158 
00159     if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
00160         char *p;
00161 
00162         sprintf(driver, "%s;Driver=%s;Setup=%s;",
00163                 drivername, dllname, dllname);
00164         p = driver;
00165         while (*p) {
00166             if (*p == ';') {
00167                 *p = '\0';
00168             }
00169             ++p;
00170         }
00171         usecnt = 0;
00172         SQLInstallDriverEx(driver, NULL, path, pathmax, &pathlen,
00173                            ODBC_INSTALL_INQUIRY, &usecnt);
00174         sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
00175                 drivername, path, dllname, path, dllname);
00176         p = driver;
00177         while (*p) {
00178             if (*p == ';') {
00179                 *p = '\0';
00180             }
00181             ++p;
00182         }
00183         sprintf(inst, "%s\\%s", path, dllname);
00184         if (dll2name) {
00185             sprintf(inst2, "%s\\%s", path, dll2name);
00186         }
00187         if (!remove && usecnt > 0) {
00188             /* first install try: copy over driver dll, keeping DSNs */
00189             if (GetFileAttributes(dllname) != INVALID_FILE_ATTRIBUTES &&
00190                 CopyFile(dllname, inst, 0) &&
00191                 CopyOrDelModules(dllname, path, 0)) {
00192                 if (dll2name != NULL) {
00193                     CopyFile(dll2name, inst2, 0);
00194                 }
00195                 return TRUE;
00196             }
00197         }
00198         mincnt = remove ? 1 : 0;
00199         while (usecnt != mincnt) {
00200             if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
00201                 break;
00202             }
00203         }
00204         if (remove) {
00205             if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
00206                 if (GetFileAttributes(dllname) != INVALID_FILE_ATTRIBUTES) {
00207                     ProcessErrorMessages("SQLRemoveDriver", 0);
00208                     return FALSE;
00209                 }
00210                 ProcessErrorMessages("SQLRemoveDriver", 1);
00211                 usecnt = 1;
00212             }
00213             if (!usecnt) {
00214                 char buf[512];
00215 
00216                 DeleteFile(inst);
00217                 /* but keep inst2 */
00218                 CopyOrDelModules(dllname, path, 1);
00219                 if (!quiet) {
00220                     sprintf(buf, "%s uninstalled.", drivername);
00221                     MessageBox(NULL, buf, "Info",
00222                                MB_ICONINFORMATION|MB_OK|MB_TASKMODAL|
00223                                MB_SETFOREGROUND);
00224                 }
00225             }
00226             if (nosys) {
00227                 goto done;
00228             }
00229             sprintf(attr, "DSN=%s;Database=", dsname);
00230             p = attr;
00231             while (*p) {
00232                 if (*p == ';') {
00233                     *p = '\0';
00234                 }
00235                 ++p;
00236             }
00237             SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
00238             goto done;
00239         }
00240         if (GetFileAttributes(dllname) == INVALID_FILE_ATTRIBUTES) {
00241             return FALSE;
00242         }
00243         if (!CopyFile(dllname, inst, 0)) {
00244             char buf[512];
00245 
00246             sprintf(buf, "Copy %s to %s failed", dllname, inst);
00247             MessageBox(NULL, buf, "CopyFile",
00248                        MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
00249             return FALSE;
00250         }
00251         if (dll2name != NULL && !CopyFile(dll2name, inst2, 0)) {
00252             char buf[512];
00253 
00254             sprintf(buf, "Copy %s to %s failed", dll2name, inst2);
00255             MessageBox(NULL, buf, "CopyFile",
00256                        MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
00257             /* but go on hoping that an SQLite engine is in place */
00258         }
00259         if (!CopyOrDelModules(dllname, path, 0)) {
00260             return FALSE;
00261         }
00262         if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
00263                                 ODBC_INSTALL_COMPLETE, &usecnt)) {
00264             ProcessErrorMessages("SQLInstallDriverEx", 0);
00265             return FALSE;
00266         }
00267         if (nosys) {
00268             goto done;
00269         }
00270         sprintf(attr, "DSN=%s;Database=;", dsname);
00271         p = attr;
00272         while (*p) {
00273             if (*p == ';') {
00274                 *p = '\0';
00275             }
00276             ++p;
00277         }
00278         SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
00279         if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
00280             ProcessErrorMessages("SQLConfigDataSource", 0);
00281             return FALSE;
00282         }
00283     } else {
00284         ProcessErrorMessages("SQLInstallDriverManager", 0);
00285         return FALSE;
00286     }
00287 done:
00288     return TRUE;
00289 }
00290 
00298 int APIENTRY
00299 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
00300         LPSTR lpszCmdLine, int nCmdShow)
00301 {
00302     char path[300], *p;
00303     int i, remove;
00304     BOOL ret[NUMDRVS];
00305 
00306     GetModuleFileName(NULL, path, sizeof (path));
00307     p = path;
00308     while (*p) {
00309         *p = tolower(*p);
00310         ++p;
00311     }
00312     p = strrchr(path, '\\');
00313     if (p == NULL) {
00314         p = path;
00315     } else {
00316         *p = '\0';
00317         ++p;
00318         SetCurrentDirectory(path);
00319     }
00320     remove = strstr(p, "uninst") != NULL;
00321     quiet = strstr(p, "instq") != NULL;
00322     nosys = strstr(p, "nosys") != NULL;
00323     for (i = 0; i < NUMDRVS; i++) {
00324 #ifdef WITH_SQLITE_DLLS
00325         p = EngineDLL[i];
00326 #else
00327         p = NULL;
00328 #endif
00329         ret[i] = InUn(remove, DriverName[i], DriverDLL[i], p, DSName[i]);
00330     }
00331     for (i = 1; i < NUMDRVS; i++) {
00332         ret[0] = ret[0] || ret[i];
00333     }
00334     if (!remove && ret[0]) {
00335         if (!quiet) {
00336             MessageBox(NULL, "SQLite ODBC Driver(s) installed.", "Info",
00337                        MB_ICONINFORMATION|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
00338         }
00339     }
00340     exit(0);
00341 }
00342 
00343 /*
00344  * Local Variables:
00345  * mode: c
00346  * c-basic-offset: 4
00347  * fill-column: 78
00348  * tab-width: 8
00349  * End:
00350  */

Generated on 1 Dec 2016 by doxygen.
Contact: chw@ch-werner.de