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 #ifdef _WIN64
00033 #define NUMDRVS 1
00034 static char *DriverName[NUMDRVS] = {
00035 "SQLite3 ODBC Driver" SEESTR
00036 };
00037 static char *DSName[NUMDRVS] = {
00038 "SQLite3 " SEESTR2 "Datasource"
00039 };
00040 static char *DriverDLL[NUMDRVS] = {
00041 "sqlite3odbc" SEEEXT ".dll"
00042 };
00043 #ifdef WITH_SQLITE_DLLS
00044 static char *EngineDLL[NUMDRVS] = {
00045 "sqlite3" SEEEXT ".dll"
00046 };
00047 #endif
00048 #else
00049 #define NUMDRVS 3
00050 static char *DriverName[NUMDRVS] = {
00051 "SQLite ODBC Driver",
00052 "SQLite ODBC (UTF-8) Driver",
00053 "SQLite3 ODBC Driver" SEESTR
00054 };
00055 static char *DSName[NUMDRVS] = {
00056 "SQLite Datasource",
00057 "SQLite UTF-8 Datasource",
00058 "SQLite3 " SEESTR2 "Datasource"
00059 };
00060 static char *DriverDLL[NUMDRVS] = {
00061 "sqliteodbc.dll",
00062 "sqliteodbcu.dll",
00063 "sqlite3odbc" SEEEXT ".dll"
00064 };
00065 #ifdef WITH_SQLITE_DLLS
00066 static char *EngineDLL[NUMDRVS] = {
00067 "sqlite.dll",
00068 "sqliteu.dll",
00069 "sqlite3.dll"
00070 };
00071 #endif
00072 #endif
00073
00074 static int quiet = 0;
00075 static int nosys = 0;
00076
00082 static BOOL
00083 ProcessErrorMessages(char *name)
00084 {
00085 WORD err = 1;
00086 DWORD code;
00087 char errmsg[301];
00088 WORD errlen, errmax = sizeof (errmsg) - 1;
00089 int rc;
00090 BOOL ret = FALSE;
00091
00092 do {
00093 errmsg[0] = '\0';
00094 rc = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
00095 if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
00096 MessageBox(NULL, errmsg, name,
00097 MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
00098 ret = TRUE;
00099 }
00100 err++;
00101 } while (rc != SQL_NO_DATA);
00102 return ret;
00103 }
00104
00112 static BOOL
00113 CopyOrDelModules(char *dllname, char *path, BOOL del)
00114 {
00115 char firstpat[MAX_PATH];
00116 WIN32_FIND_DATA fdata;
00117 HANDLE h;
00118 DWORD err;
00119
00120 if (strncmp(dllname, "sqlite3", 7)) {
00121 return TRUE;
00122 }
00123 firstpat[0] = '\0';
00124 if (del) {
00125 strcpy(firstpat, path);
00126 strcat(firstpat, "\\");
00127 }
00128 strcat(firstpat, "sqlite3_mod*.dll");
00129 h = FindFirstFile(firstpat, &fdata);
00130 if (h == INVALID_HANDLE_VALUE) {
00131 return TRUE;
00132 }
00133 do {
00134 if (del) {
00135 DeleteFile(fdata.cFileName);
00136 } else {
00137 char buf[1024];
00138
00139 sprintf(buf, "%s\\%s", path, fdata.cFileName);
00140 if (!CopyFile(fdata.cFileName, buf, 0)) {
00141 sprintf(buf, "Copy %s to %s failed", fdata.cFileName, path);
00142 MessageBox(NULL, buf, "CopyFile",
00143 MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
00144 FindClose(h);
00145 return FALSE;
00146 }
00147 }
00148 } while (FindNextFile(h, &fdata));
00149 err = GetLastError();
00150 FindClose(h);
00151 return err == ERROR_NO_MORE_FILES;
00152 }
00153
00163 static BOOL
00164 InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
00165 {
00166 char path[301], driver[300], attr[300], inst[400], inst2[400];
00167 WORD pathmax = sizeof (path) - 1, pathlen;
00168 DWORD usecnt, mincnt;
00169
00170 if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
00171 char *p;
00172
00173 sprintf(driver, "%s;Driver=%s;Setup=%s;",
00174 drivername, dllname, dllname);
00175 p = driver;
00176 while (*p) {
00177 if (*p == ';') {
00178 *p = '\0';
00179 }
00180 ++p;
00181 }
00182 usecnt = 0;
00183 SQLInstallDriverEx(driver, NULL, path, pathmax, &pathlen,
00184 ODBC_INSTALL_INQUIRY, &usecnt);
00185 sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
00186 drivername, path, dllname, path, dllname);
00187 p = driver;
00188 while (*p) {
00189 if (*p == ';') {
00190 *p = '\0';
00191 }
00192 ++p;
00193 }
00194 sprintf(inst, "%s\\%s", path, dllname);
00195 if (dll2name) {
00196 sprintf(inst2, "%s\\%s", path, dll2name);
00197 }
00198 if (!remove && usecnt > 0) {
00199
00200 if (GetFileAttributes(dllname) != INVALID_FILE_ATTRIBUTES &&
00201 CopyFile(dllname, inst, 0) &&
00202 CopyOrDelModules(dllname, path, 0)) {
00203 if (dll2name != NULL) {
00204 CopyFile(dll2name, inst2, 0);
00205 }
00206 return TRUE;
00207 }
00208 }
00209 mincnt = remove ? 1 : 0;
00210 while (usecnt != mincnt) {
00211 if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
00212 break;
00213 }
00214 }
00215 if (remove) {
00216 if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
00217 ProcessErrorMessages("SQLRemoveDriver");
00218 return FALSE;
00219 }
00220 if (!usecnt) {
00221 char buf[512];
00222
00223 DeleteFile(inst);
00224
00225 CopyOrDelModules(dllname, path, 1);
00226 if (!quiet) {
00227 sprintf(buf, "%s uninstalled.", drivername);
00228 MessageBox(NULL, buf, "Info",
00229 MB_ICONINFORMATION|MB_OK|MB_TASKMODAL|
00230 MB_SETFOREGROUND);
00231 }
00232 }
00233 if (nosys) {
00234 goto done;
00235 }
00236 sprintf(attr, "DSN=%s;Database=sqlite.db;", dsname);
00237 p = attr;
00238 while (*p) {
00239 if (*p == ';') {
00240 *p = '\0';
00241 }
00242 ++p;
00243 }
00244 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
00245 goto done;
00246 }
00247 if (GetFileAttributes(dllname) == INVALID_FILE_ATTRIBUTES) {
00248 return FALSE;
00249 }
00250 if (!CopyFile(dllname, inst, 0)) {
00251 char buf[512];
00252
00253 sprintf(buf, "Copy %s to %s failed", dllname, inst);
00254 MessageBox(NULL, buf, "CopyFile",
00255 MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
00256 return FALSE;
00257 }
00258 if (dll2name != NULL && !CopyFile(dll2name, inst2, 0)) {
00259 char buf[512];
00260
00261 sprintf(buf, "Copy %s to %s failed", dll2name, inst2);
00262 MessageBox(NULL, buf, "CopyFile",
00263 MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
00264
00265 }
00266 if (!CopyOrDelModules(dllname, path, 0)) {
00267 return FALSE;
00268 }
00269 if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
00270 ODBC_INSTALL_COMPLETE, &usecnt)) {
00271 ProcessErrorMessages("SQLInstallDriverEx");
00272 return FALSE;
00273 }
00274 if (nosys) {
00275 goto done;
00276 }
00277 sprintf(attr, "DSN=%s;Database=sqlite.db;", dsname);
00278 p = attr;
00279 while (*p) {
00280 if (*p == ';') {
00281 *p = '\0';
00282 }
00283 ++p;
00284 }
00285 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
00286 if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
00287 ProcessErrorMessages("SQLConfigDataSource");
00288 return FALSE;
00289 }
00290 } else {
00291 ProcessErrorMessages("SQLInstallDriverManager");
00292 return FALSE;
00293 }
00294 done:
00295 return TRUE;
00296 }
00297
00305 int APIENTRY
00306 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
00307 LPSTR lpszCmdLine, int nCmdShow)
00308 {
00309 char path[300], *p;
00310 int i, remove;
00311 BOOL ret[3];
00312
00313 GetModuleFileName(NULL, path, sizeof (path));
00314 p = path;
00315 while (*p) {
00316 *p = tolower(*p);
00317 ++p;
00318 }
00319 p = strrchr(path, '\\');
00320 if (p == NULL) {
00321 p = path;
00322 } else {
00323 *p = '\0';
00324 ++p;
00325 SetCurrentDirectory(path);
00326 }
00327 remove = strstr(p, "uninst") != NULL;
00328 quiet = strstr(p, "instq") != NULL;
00329 nosys = strstr(p, "nosys") != NULL;
00330 for (i = 0; i < NUMDRVS; i++) {
00331 #ifdef WITH_SQLITE_DLLS
00332 p = EngineDLL[i];
00333 #else
00334 p = NULL;
00335 #endif
00336 ret[i] = InUn(remove, DriverName[i], DriverDLL[i], p, DSName[i]);
00337 }
00338 for (i = 1; i < NUMDRVS; i++) {
00339 ret[0] = ret[0] || ret[i];
00340 }
00341 if (!remove && ret[0]) {
00342 if (!quiet) {
00343 MessageBox(NULL, "SQLite ODBC Driver(s) installed.", "Info",
00344 MB_ICONINFORMATION|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
00345 }
00346 }
00347 exit(0);
00348 }
00349