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 #if defined(WITH_SQLITE_DLLS) && (WITH_SQLITE_DLLS <= 1)
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
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
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
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 #if defined(WITH_SQLITE_DLLS) && (WITH_SQLITE_DLLS <= 1)
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
00345
00346
00347
00348
00349
00350