unit CheckODBCAliasUnit;
interface
type
SQLHANDLE = LongInt;
SQLHENV = SQLHANDLE;
SQLSMALLINT = smallint;
SQLINTEGER = LongInt;
SQLPOINTER = Pointer;
SQLRETURN = SQLSMALLINT;
SQLUSMALLINT = Word;
PSQLCHAR = PChar;
PSQLSMALLINT = ^SQLSMALLINT;
const
SQL_HANDLE_ENV = 1;
SQL_NULL_HANDLE = 0;
SQL_SUCCESS = 0;
SQL_ATTR_ODBC_VERSION = 200;
SQL_OV_ODBC3 = 3;
SQL_SUCCESS_WITH_INFO = 1;
SQL_MAX_DSN_LENGTH = 32;
SQL_FETCH_FIRST = 2;
SQL_FETCH_NEXT = 1;
ODBC_ADD_DSN = 1;
ODBC_CONFIG_DSN = 2;
procedure CheckODBCALias(AODBCName, ADatabaseName: string);
function GetODBCAliasDatabasePath(AODBCName: string): string;
procedure LoadODBC;
procedure UnLoadODBC;
type
TSQLConfigDataSource = function(
hwndParent: Integer;
fRequest: Integer;
lpszDriverString: string;
lpszAttributes: string): Integer; stdcall;
TSQLAllocHandle = function(HandleType: SQLSMALLINT;
InputHandle: SQLHANDLE;
var OutputHandlePtr: SQLHANDLE): SQLRETURN; stdcall;
TSQLSetEnvAttr = function(EnvironmentHandle: SQLHENV;
Attribute: SQLINTEGER; Value: SQLPOINTER;
StringLength: SQLINTEGER) : SQLRETURN; stdcall;
TSQLFreeHandle = function(HandleType: SQLSMALLINT;
Handle: SQLHANDLE): SQLRETURN; stdcall;
TSQLDataSources = function(EnvironmentHandle: SQLHENV;
Direction: SQLUSMALLINT; ServerName: PSQLCHAR;
BufferLength1: SQLSMALLINT; NameLength1: PSQLSMALLINT;
Description: PSQLCHAR; BufferLength2: SQLSMALLINT;
NameLength2: PSQLSMALLINT) : SQLRETURN; stdcall;
implementation
uses
Windows, SysUtils, Classes, VCLUtils;
var
OdbcHMODULE: HMODULE;
Odbc1HMODULE: HMODULE;
SQLConfigDataSource: TSQLConfigDataSource;
SQLAllocHandle: TSQLAllocHandle;
SQLSetEnvAttr: TSQLSetEnvAttr;
SQLFreeHandle: TSQLFreeHandle;
SQLDataSources: TSQLDataSources;
function GetAdresstoFunction(AODBCModule: HMODULE; FunctionName: string): FARPROC;
begin
Result := GetProcAddress(AODBCModule, Pchar(FunctionName));
if Result = nil then
begin
raise Exception.create('Íå ìîãó çàãðóçèòü ôóíêöèþ '+ FunctionName + #13+
SysErrorMessage(GetLastError));
end;
end;
procedure LoadODBC;
begin
OdbcHMODULE := LoadLibrary('ODBC32.DLL');
if OdbcHMODULE = 0 then
raise Exception.Create(SysErrorMessage(GetLastError));
SQLAllocHandle := GetAdresstoFunction(OdbcHMODULE, 'SQLAllocHandle');
SQLSetEnvAttr := GetAdresstoFunction(OdbcHMODULE, 'SQLSetEnvAttr');
SQLFreeHandle := GetAdresstoFunction(OdbcHMODULE, 'SQLFreeHandle');
SQLDataSources := GetAdresstoFunction(OdbcHMODULE, 'SQLDataSources');
Odbc1HMODULE := LoadLibrary('ODBCCP32.DLL');
if Odbc1HMODULE = 0 then
raise Exception.Create(SysErrorMessage(GetLastError));
SQLConfigDataSource := GetAdresstoFunction(Odbc1HMODULE, 'SQLConfigDataSource');
end;
procedure UnLoadODBC;
begin
Delay(100);
if OdbcHMODULE <> 0 then
begin
if not FreeLibrary(OdbcHMODULE) then
begin
raise Exception.Create(SysErrorMessage(GetLastError));
end;
end;
if Odbc1HMODULE <> 0 then
begin
if not FreeLibrary(Odbc1HMODULE) then
begin
raise Exception.Create(SysErrorMessage(GetLastError));
end;
end;
end;
function GetHENV: SQLHENV;
var
AODBCHandle: SQLHENV;
begin
AODBCHandle := 0;
LoadODBC;
if SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, AODBCHandle) <> SQL_SUCCESS then
raise Exception.Create('Îøèáêà àëîêàöèÿ ODBC õýíäëà.');
try
if not(SQLSetEnvAttr(AODBCHandle, SQL_ATTR_ODBC_VERSION, SQLPOINTER(SQL_OV_ODBC3), 0)
in [SQL_SUCCESS,SQL_SUCCESS_WITH_INFO]) then
raise Exception.Create('Îøèáêà ïîëó÷åíèÿ àòðèáóòîâ ODBC õýíäëà.' );
except
if AODBCHandle <> 0 then
begin
SQLFreeHandle(SQL_HANDLE_ENV, AODBCHandle);
end;
raise;
end;
Result := AODBCHandle;
end;
procedure GetDatSourceNames(Alist: TStrings);
var
ServerName: array [0..SQL_MAX_DSN_LENGTH] of Char;
sl: SQLSMALLINT;
sqlResult: integer;
AODBCEnviromentHandle: SQLHENV;
begin
Alist.Clear;
AODBCEnviromentHandle := GetHENV;
if SQLDataSources(AODBCEnviromentHandle, SQL_FETCH_FIRST,
ServerName, SQL_MAX_DSN_LENGTH, @sl,
nil, 0, nil) = SQL_SUCCESS then
repeat
Alist.add( StrPas(ServerName));
sqlresult := SQLDataSources(AODBCEnviromentHandle, SQL_FETCH_NEXT,
ServerName, SQL_MAX_DSN_LENGTH, @sl,
nil, 0, nil)
until (sqlResult <> SQL_SUCCESS) and (sqlResult <> SQL_SUCCESS_WITH_INFO)
end;
procedure CheckODBCALias(AODBCName, ADatabaseName: string);
var
AODBCDSN: TStringList;
AParameters: string;
begin
AODBCDSN := TStringList.Create;
try
GetDatSourceNames(AODBCDSN);
if AODBCDSN.IndexOf(AODBCName) <> -1 then
begin
AParameters := 'DSN=' + AODBCName + ';DBQ=' + ADatabaseName;
SQLConfigDataSource(SQL_NULL_HANDLE, ODBC_CONFIG_DSN,
'Microsoft Access Driver (*.mdb)', AParameters)
end
else
begin
AParameters := 'DSN=' + AODBCName + ';DBQ=' + ADatabaseName;
SQLConfigDataSource(SQL_NULL_HANDLE, ODBC_ADD_DSN,
'Microsoft Access Driver (*.mdb)', AParameters);
end;
finally
AODBCDSN.Free;
UnLoadODBC;
end;
end;
function GetODBCAliasDatabasePath(AODBCName: string): string;
var
AODBCDSN: TStringList;
AParameters: string;
begin
AODBCDSN := TStringList.Create;
try
GetDatSourceNames(AODBCDSN);
finally
AODBCDSN.Free;
UnLoadODBC;
end;
end;
end.