⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 install.c

📁 这个是内存数据库的客户端
💻 C
字号:
/* * The contents of this file are subject to the MonetDB Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The Original Code is the MonetDB Database System. * * The Initial Developer of the Original Code is CWI. * Portions created by CWI are Copyright (C) 1997-2007 CWI. * All Rights Reserved. */#include "ODBCGlobal.h"#include <winver.h>#include <shlwapi.h>#include <string.h>#include <stdio.h>#include <malloc.h>#ifdef __MINGW32__#define DLL "-0.dll"#else #define DLL ".dll"#endifstatic char *DriverName = "MonetDB ODBC Driver";static char *DataSourceName = "MonetDB";static char *InstallDLLs[] = {	"libMonetODBC" DLL,	"libMonetODBCs" DLL,	"libMapi" DLL,	"libstream" DLL,	"libmutils" DLL,	NULL};#define DriverDLL	(InstallDLLs[0])#define DriverDLLs	(InstallDLLs[1])/* General error handler for installer functions */static BOOLProcessSQLErrorMessages(const char *func){	WORD errnr = 1;	DWORD errcode;	char errmsg[300];	WORD errmsglen;	int rc;	BOOL func_rc = FALSE;	do {		errmsg[0] = '\0';		rc = SQLInstallerError(errnr, &errcode, errmsg, sizeof(errmsg), &errmsglen);		if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {			MessageBox(NULL, errmsg, func, MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);			func_rc = TRUE;		}		errnr++;	} while (rc != SQL_NO_DATA);	return func_rc;}static voidProcessSysErrorMessage(DWORD err, const char *func){	char *lpMsgBuf;	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & lpMsgBuf, 0, NULL);	MessageBox(NULL, (LPCTSTR) lpMsgBuf, func, MB_OK | MB_ICONINFORMATION);	LocalFree(lpMsgBuf);}int CheckIfFileExists(const char *filepath, const char *filename){	char buf[300];	LPTSTR b;	return SearchPath(filepath, filename, NULL, sizeof(buf), buf, &b) > 0;}static BOOLGetFileVersion(char *filepath, char *version, int maxversionlen){	DWORD handle = 0;	DWORD versioninfosize;	DWORD error;	PVOID fileinfo;	PBYTE versioninfo;	PDWORD translation = NULL;	UINT length = 0;	char string[512] = "";	LPSTR versionstr;	versioninfosize = GetFileVersionInfoSize(filepath, &handle);	if (!versioninfosize) {		error = GetLastError();		return FALSE;	}	fileinfo = (PVOID) malloc(versioninfosize);	versioninfo = (PBYTE) malloc(versioninfosize);	if (!GetFileVersionInfo(filepath, handle, versioninfosize, fileinfo)) {		error = GetLastError();		free(fileinfo);		free(versioninfo);		return FALSE;	}	if (!VerQueryValue(fileinfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID *) & translation, &length)) {		error = GetLastError();		free(fileinfo);		free(versioninfo);		return FALSE;	}	snprintf(string, sizeof(string), "\\StringFileInfo\\%04x%04x\\FileVersion", LOWORD(*translation), HIWORD(*translation));	if (!VerQueryValue(fileinfo, string, (PVOID *) & versionstr, &length)) {		error = GetLastError();		free(fileinfo);		free(versioninfo);		return FALSE;	}	if (lstrlen(versionstr) >= maxversionlen)		lstrcpyn(version, versionstr, maxversionlen - 1);	else		lstrcpy(version, versionstr);	free(fileinfo);	free(versioninfo);	return TRUE;}static BOOLVersionCheckCopyFile(const char *srcpath, const char *dstpath, const char *filename){	BOOL fileexists = FALSE;	char srcfile[512];	char dstfile[512];	char srcfileVersion[512];	char dstfileVersion[512];	snprintf(srcfile, sizeof(srcfile), "%s\\%s", srcpath, filename);	snprintf(dstfile, sizeof(dstfile), "%s\\%s", dstpath, filename);	if (CheckIfFileExists(dstpath, filename)) {		if (!GetFileVersion(srcfile, srcfileVersion, sizeof(srcfileVersion)) || !GetFileVersion(dstfile, dstfileVersion, (int) sizeof(dstfileVersion)))			return FALSE;		if (strcmp(dstfileVersion, srcfileVersion) >= 0) {			/* file is up-to-date, so don't copy */			return TRUE;		}		/* file exists but is not up-to-date, so copy */		fileexists = TRUE;		/* move the existing file out of the way */		/* reuse dstfileVersion as temporary file name */		strcpy(dstfileVersion, dstfile);		/* change extension */		dstfileVersion[strlen(dstfileVersion) - 1] = '~';		if (!MoveFileEx(dstfile, dstfileVersion, MOVEFILE_REPLACE_EXISTING)) {			snprintf(srcfileVersion, sizeof(srcfileVersion), "Unable to move %s to %s\n", dstfile, dstfileVersion);			MessageBox(NULL, srcfileVersion, "VersionCheckCopyFile", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);			return FALSE;		}	}	/* else file does not exist, so copy */	if (!CopyFile(srcfile, dstfile, FALSE)) {		snprintf(srcfileVersion, sizeof(srcfileVersion), "Unable to copy %s to %s\n", srcfile, dstfile);		if (fileexists) {			/* move original file back */			MoveFileEx(dstfileVersion, dstfile, MOVEFILE_REPLACE_EXISTING);		}		MessageBox(NULL, srcfileVersion, "VersionCheckCopyFile", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);		return FALSE;	}	if (fileexists) {		/* tell system to remove original file on reboot */		if (!MoveFileEx(dstfileVersion, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) {			snprintf(srcfileVersion, sizeof(srcfileVersion), "Unable to delete %s\n", dstfileVersion);			MessageBox(NULL, srcfileVersion, "VersionCheckCopyFile", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);			return FALSE;		}	}	return TRUE;}static BOOLInstallMyDriver(const char *driverpath){	char driver[300];	char inpath[301];	char outpath[301];	WORD outpathlen;	DWORD usagecount;	char *p;	char **dll;	/* the correct format of driver keywords are	 * "DriverName\0Driver=xxxxxx.DLL\0Setup=xxxxxx.DLL\0\0" */	snprintf(driver, sizeof(driver), "%s;Driver=%s;Setup=%s;", DriverName, DriverDLL, DriverDLLs);	for (p = driver; *p; p++)		if (*p == ';')			*p = '\0';	/* the driver array is filled in before calling	 * SQLInstallDriverEx so that SQLInstallDriverEx will return	 * where to install the driver in the inpath */	SQLInstallDriverEx(driver, NULL, inpath, sizeof(inpath), &outpathlen, ODBC_INSTALL_INQUIRY, &usagecount);	/* the correct format of driver keywords are	 * "DriverName\0Driver=c:\winnt\system32\xxxxxx.DLL\0Setup=c:\winnt\system32\xxxxxx.DLL\0\0" */	snprintf(driver, sizeof(driver),		 "%s;Driver=%s\\%s;Setup=%s\\%s;APILevel=1;"		 "ConnectFunctions=YYY;DriverODBCVer=%s;SQLLevel=3;",		 DriverName, inpath, DriverDLL, inpath, DriverDLLs, MONETDB_ODBC_VER);	for (p = driver; *p; p++)		if (*p == ';')			*p = '\0';	for (dll = InstallDLLs; *dll; dll++)		if (!VersionCheckCopyFile(driverpath, inpath, *dll) && ProcessSQLErrorMessages("SQLInstallDriverEx"))			return FALSE;	/* call SQLInstallDriverEx to install the driver in the	 * registry */	if (!SQLInstallDriverEx(driver, inpath, outpath, sizeof(outpath), &outpathlen, ODBC_INSTALL_COMPLETE, &usagecount) && ProcessSQLErrorMessages("SQLInstallDriverEx"))		return FALSE;	return TRUE;}static BOOLRemoveMyDriver(){	char buf[300];	char dirname[300];	WORD len;	DWORD usagecount;	DWORD valtype, valsize, rc;	char *p;	char **dll;	/* most of this is equivalent to what SQLRemoveDriver is	   suppposed to do, except that it consistently causes a	   crash, so we do it ourselves */	snprintf(buf, sizeof(buf), "SOFTWARE\\ODBC\\ODBCINST.INI\\%s", DriverName);	valsize = sizeof(usagecount);	usagecount = 0;	valtype = REG_DWORD;	rc = SHGetValue(HKEY_LOCAL_MACHINE, buf, "UsageCount", &valtype, &usagecount, &valsize);	if (rc == ERROR_FILE_NOT_FOUND) {		/* not installed, do nothing */		exit(0);	}	if (rc != ERROR_SUCCESS) {		ProcessSysErrorMessage(rc, "one");		return FALSE;	}	if (usagecount > 1) {		usagecount--;		rc = SHSetValue(HKEY_LOCAL_MACHINE, buf, "UsageCount", REG_DWORD, &usagecount, sizeof(usagecount));		if (rc != ERROR_SUCCESS) {			ProcessSysErrorMessage(rc, "two");			return FALSE;		}		return TRUE;	}	rc = SHDeleteKey(HKEY_LOCAL_MACHINE, buf);	if (rc != ERROR_SUCCESS) {		ProcessSysErrorMessage(rc, "three");		return FALSE;	}	rc = SHDeleteValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\ODBC\\ODBCINST.INI\\ODBC Drivers", DriverName);	if (rc != ERROR_SUCCESS) {		ProcessSysErrorMessage(rc, "four");		return FALSE;	}	/* figure out where the files were installed */	snprintf(buf, sizeof(buf), "%s;Driver=%s;Setup=%s;", DriverName, DriverDLL, DriverDLLs);	for (p = buf; *p; p++)		if (*p == ';')			*p = '\0';	SQLInstallDriverEx(buf, NULL, dirname, sizeof(dirname), &len, ODBC_INSTALL_INQUIRY, &usagecount);	/* and the delete them */	for (dll = InstallDLLs; *dll; dll++) {		snprintf(buf, sizeof(buf), "%s\\%s", dirname, *dll);		DeleteFile(buf);	}	return TRUE;}static voidCreateAttributeString(char *attrs, size_t len){	snprintf(attrs, len, "DSN=%s;Server=localhost;Database=;UID=monetdb;PWD=monetdb;", DataSourceName);	for (; *attrs; attrs++)		if (*attrs == ';')			*attrs = '\0';}static BOOLAddMyDSN(){	char attrs[200];	CreateAttributeString(attrs, sizeof(attrs));	/* I choose to remove the DSN if it already existed */	SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, DriverName, attrs);	/* then create a new DSN */	if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, DriverName, attrs) && ProcessSQLErrorMessages("SQLConfigDataSource"))		return FALSE;	return TRUE;}static BOOLRemoveMyDSN(){	char buf[200];	char *p;	snprintf(buf, sizeof(buf), "DSN=%s;", DataSourceName);	for (p = buf; *p; p++)		if (*p == ';')			*p = 0;	SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, DriverName, buf);	return TRUE;}static BOOLInstall(const char *driverpath){	char path[300];	WORD pathlen;	BOOL rc;	DWORD usagecount;	/* first, retrieve the path the driver should be installed to	 * in path */	if (!SQLInstallDriverManager(path, sizeof(path), &pathlen) && ProcessSQLErrorMessages("SQLInstallDriverManager"))		return FALSE;	if (!CheckIfFileExists(path, "odbc32.dll")) {		MessageBox(NULL, "You must install MDAC before you can use the ODBC driver", "Install", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);		SQLRemoveDriverManager(&usagecount);		return FALSE;	}	rc = InstallMyDriver(driverpath);	if (rc) {		/* after the driver is installed create the new DSN */		rc = AddMyDSN();	}	if (!rc)		SQLRemoveDriverManager(&usagecount);	return rc;}static BOOLUninstall(){	DWORD usagecount;	RemoveMyDSN();	RemoveMyDriver();	SQLRemoveDriverManager(&usagecount);	return TRUE;}intmain(int argc, char **argv){	char *buf = malloc(strlen(argv[0]) + 30);	char *p;	strcpy(buf, argv[0]);	if ((p = strrchr(buf, '\\')) != 0 || (p = strrchr(buf, '/')) != 0)		*p = 0;	else		strcpy(buf, ".");	strcat(buf, "\\lib");	if (argc != 2) {		MessageBox(NULL, "/Install or /Uninstall argument expected", argv[0], MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);		exit(1);	}	if (strcmp("/Install", argv[1]) == 0) {		if (!Install(buf)) {			MessageBox(NULL, "ODBC Install Failed", argv[0], MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);			exit(1);		}		/* create a file to indicate that we've installed the driver */		strcat(buf, "\\ODBCDriverInstalled.txt");		CloseHandle(CreateFile(buf, READ_CONTROL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL));	} else if (strcmp("/Uninstall", argv[1]) == 0) {		/* only uninstall the driver if the file exists */		strcat(buf, "\\ODBCDriverInstalled.txt");		if (!DeleteFile(buf)) {			if (GetLastError() == ERROR_FILE_NOT_FOUND) {				/* not installed, so don't uninstall */				return 0;			}			MessageBox(NULL, "Cannot delete file for wrong reason", argv[0], MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);		}		if (!Uninstall()) {			MessageBox(NULL, "ODBC Uninstall Failed", argv[0], MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);			exit(1);		}	} else {		MessageBox(NULL, "/Install or /Uninstall argument expected", argv[0], MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);		exit(1);	}	free(buf);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -