home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1998 December
/
PCWorld_1998-12_cd.iso
/
software
/
sybase
/
ASA
/
asa60.exe
/
data1.cab
/
src_files
/
esqldll.c
Wrap
C/C++ Source or Header
|
1998-07-27
|
12KB
|
367 lines
/****************************************************************
* Copyright (C) 1988-1998, by Sybase, Inc. *
* All rights reserved. No part of this software may be *
* reproduced in any form or by any means - graphic, *
* electronic or mechanical, including photocopying, *
* recording, taping or information storage and retrieval *
* systems - except with the written permission of *
* Sybase, Inc. *
****************************************************************/
/*
Overview:
~~~~~~~~~
By using this module with your embedded SQL application,
your application will be more robust in its ability to
locate the database interface DLL, and you will not need
to link against the import library for the DLL.
Usage:
~~~~~~
1) Your program must call db_init_dll to load the DLL, and must
call db_fini_dll to free the DLL. db_init_dll must be called
before any function in the database interface, and no function
in the interface can be called after db_fini_dll.
See below for more details on db_init_dll and db_fini_dll.
Note that you must still call db_init and db_fini.
2) You must #include the file esqldll.h before the
EXEC SQL INCLUDE SQLCA statement or #include <sqlca.h> line
in your embedded SQL program.
3) You must ensure that a SQL OS macro is defined when compiling this file.
(esqldll.c>. The header file sqlca.h, which is included by this file,
attempts to determine the appropriate macro and defines it. However,
certain combinations of platforms and compilers may cause this to fail.
In this case, you must add a #define to the top of this file, or
make the definition by using a compiler option.
Macro Platforms
~~~~~ ~~~~~~~~~
_SQL_OS_WINNT 32-bit Windows (NT, 95, Win32s)
_SQL_OS_WINDOWS 16-bit Windows (3.1, 3.11)
_SQL_OS_OS232 32-bit OS/2
4) Compile this file.
5) Instead of linking against the imports library, link the object
module "esqldll.obj" with your embedded SQL application objects.
*/
#define _NO_FUNC_INFO
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlca.h"
#include "sqldef.h"
#include "esqldll.h"
#if defined( _SQL_OS_WINDOWS ) || defined( _SQL_OS_WINNT )
#include <windows.h>
#elif defined ( _SQL_OS_OS232 )
#define INCL_DOSMODULEMGR
#include <os2.h>
#endif
/****************************************/
/* declare & initialize version externs */
/****************************************/
extern a_sqlpp_version_number _ESQL_Version6_ = SQLPP_DBLIB_VERSION;
extern a_sqlpp_version_number _ESQL_Version4_ = 4;
#if defined( _SQL_OS_WINNT )
extern unsigned short _ESQL_OS_WINNT_ = SQLPP_DBLIB_VERSION;
#define _DLL_SUBDIR "win32\\"
#define _WINNT_DLL_NAME "dblib6.dll"
#define _WIN32s_DLL_NAME "dblib6s.dll"
#elif defined( _SQL_OS_WINDOWS )
extern unsigned short _ESQL_OS_WINDOWS_ = SQLPP_DBLIB_VERSION;
#define _DLL_SUBDIR "win\\"
#define _DLL_NAME "dblib6w.dll"
#elif defined( _SQL_OS_OS232 )
extern unsigned short _ESQL_OS_OS232_ = SQLPP_DBLIB_VERSION;
#define _DLL_SUBDIR "os2\\"
#define _DLL_NAME "dblib6" // don't include .dll in name
#else
#error Dynamic DLL loading not supported under this OS.
#endif
/******************************/
/* declare & initialize SQLCA */
/******************************/
extern struct sqlca sqlca = {
"SQLCA ", /* sqlcaid */
sizeof( SQLCA ), /* sqlabc */
0L, /* sqlcode */
0, /* sqlerrml */
"", /* sqlerrmc */
{ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' }, /* sqlerrp */
{0L, 0L, 0L, 0L, 0L, 0L}, /* sqlerrd */
{0}, /* sqlwarn */
{0,0,0,0,0,0} /* sqlstate */
};
extern struct sqlca _fd_ *sqlcaptr = { &sqlca };
/******************************/
/* Declare function pointers */
/******************************/
#define FUNC_INFO( scope, rettype, call, fname, parms ) \
rettype ( call _fd_ * fname ) parms;
#include "sqlfuncs.h"
#undef FUNC_INFO
/********************************/
/* Open DLL and assign pointers */
/********************************/
#if defined( _SQL_OS_WINNT ) || defined( _SQL_OS_OS232 )
static HMODULE dll_handle;
#elif defined( _SQL_OS_WINDOWS )
static HINSTANCE dll_handle;
#endif
/********************************************************/
/* Functions for opening/closing database interface DLL */
/********************************************************/
#define _SQL_REGISTRY_KEY "Software\\Sybase\\Adaptive Server Anywhere\\6.0"
#define _SQL_REGISTRY_FIELD "Location"
#define _SQL_INI_FILE "asany.ini"
#define _SQL_INI_SECTION "6.0"
#define _SQL_INI_KEY "Location"
extern unsigned short db_fini_dll( void )
/*
** This function unloads the DLL from the application.
** It returns zero if unsuccessful and zero if successful.
*/
{
#if defined( _SQL_OS_WINNT )
return( FreeLibrary( dll_handle ) );
#elif defined( _SQL_OS_WINDOWS )
FreeLibrary( dll_handle );
return( TRUE );
#elif defined( _SQL_OS_OS232 )
return( DosFreeModule( dll_handle ) );
#endif
}
static unsigned short i_load_dll( char *path, int *wrongversion )
/*
** This function attemps to load the DLL. The path
** parameter should be a fully qualified path.
** If it loads successfully the function pointers
** are assigned and the version of the DLL is checked.
*/
{
#if defined( _SQL_OS_OS232 )
long result;
char loaderror[100];
#endif
#if defined( _SQL_OS_WINNT )
dll_handle = LoadLibrary( path );
if( dll_handle == NULL ) {
return( FALSE );
}
#elif defined( _SQL_OS_WINDOWS )
dll_handle = LoadLibrary( path );
if( dll_handle < HINSTANCE_ERROR ) {
return( FALSE );
}
#elif defined( _SQL_OS_OS232 )
result = DosLoadModule( (PSZ) loaderror, sizeof( loaderror ), (PSZ) path, &dll_handle );
if( result != 0 ) {
return( FALSE );
}
#endif
#if defined( _SQL_OS_WINDOWS ) || defined( _SQL_OS_WINNT )
#define FUNC_INFO( scope, rettype, call, fname, parms ) \
fname = ( void _fd_ * ) GetProcAddress( dll_handle, #fname );
#elif defined( _SQL_OS_OS232 )
#define FUNC_INFO( scope, rettype, call, fname, parms ) \
result = DosQueryProcAddr( dll_handle, 0, (PSZ) #fname, (PFN *) &fname );
#endif
#include "sqlfuncs.h"
#undef FUNC_INFO
if( db_version_check == NULL || !db_version_check( SQLPP_DBLIB_VERSION ) ) {
db_fini_dll(); /* free the DLL if version doesn't match */
*wrongversion = TRUE;
return( FALSE );
} else {
return( TRUE );
}
}
static void i_get_dll_name( char *path, int subdir )
/*
** If subdir = TRUE, this function appends a subdirectory
** and dllname to path.
** If subdir = FALSE, this function only appends the dllname
** to path.
** The subdirectory and dllname are appropriate for the
** specified platform.
*/
{
int len;
#if defined( _SQL_OS_WINNT )
OSVERSIONINFO osinfo;
#endif
/* Ensure there is a trailing slash */
len = strlen( path );
if( len > 0 && path[ len - 1 ] != '\\' ) {
path[ len ] = '\\';
path[ len + 1 ] = '\0';
}
if( subdir ) {
strcat( path, _DLL_SUBDIR );
}
#if defined( _SQL_OS_WINNT )
/* Check if we are running under win32s */
osinfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
GetVersionEx( &osinfo );
if( osinfo.dwPlatformId == VER_PLATFORM_WIN32s ) {
strcat( path, _WIN32s_DLL_NAME );
} else {
strcat( path, _WINNT_DLL_NAME );
}
#else
strcat( path, _DLL_NAME );
#endif
}
#if defined( _SQL_OS_WINNT )
static unsigned short AccessRegistry( HKEY hive, unsigned char *dllname )
{
long result;
HKEY key;
DWORD length;
result = RegOpenKeyEx( hive, _SQL_REGISTRY_KEY, 0L, KEY_ALL_ACCESS, &key );
if( result == ERROR_SUCCESS ) {
length = _MAX_PATH;
result = RegQueryValueEx( key, _SQL_REGISTRY_FIELD, NULL, NULL, dllname, &length );
RegCloseKey( key );
}
return( result == ERROR_SUCCESS );
}
#endif
extern unsigned short db_init_dll( char **paths )
/*
** This function uses a list of paths to the Adaptive Server Anywhere directory
** to try to load the database interface DLL. If the DLL cannot be
** found in any of these paths, then it looks for the location of the SQL
** Anywhere installation in the registry to locate the DLL (only under NT
** or 95). If that fails, it checks the environment variable for the
** location of the installation. If that fails, it lets the OS search
** the PATH for the DLL.
**
** The list of paths is passed as a pointer to an array of char pointers.
** The last pointer in the array must be NULL to signal the
** end of the array.
** Note that the dll filename will be appended to this path.
** For example, if you pass in the path
** "c:\asa60" and compile for WINNT, the function will look for
** "c:\asa60\dblib6.dll".
**
** This function must be called before any other database
** interface function is called.
**
** Note: If you are linking the database interface import library
** with your application then you should not call this function.
**
** Return values: (these macros are defined in sqldef.h)
** ESQLDLL_OK - dll was loaded and successfully
** ESQLDLL_DLL_NOT_FOUND - no DLL was located in any of the paths
** ESQLDLL_WRONG_VERSION - at least one copy of the DLL was located,
** but all of them were the wrong version.
*/
{
int gotdll = FALSE;
int wrongversion = FALSE;
int n;
char dllname[_MAX_PATH];
if( paths != NULL ) {
for( n = 0; paths[n] != NULL && !gotdll; n++ ) {
strcpy( dllname, paths[n] );
i_get_dll_name( dllname, FALSE );
gotdll = i_load_dll( dllname, &wrongversion );
}
}
#if defined( _SQL_OS_WINNT )
/* Look up the Adaptive Server Anywhere path in the registry */
if( !gotdll ) {
if( AccessRegistry( HKEY_CURRENT_USER, (unsigned char *) dllname )
|| AccessRegistry( HKEY_LOCAL_MACHINE, (unsigned char *) dllname ) ) {
i_get_dll_name( dllname, TRUE );
gotdll = i_load_dll( dllname, &wrongversion );
}
}
#elif defined( _SQL_OS_WINDOWS )
/* Look up the Adaptive Server Anywhere path in the .ini file */
if( !gotdll ) {
if( GetPrivateProfileString( _SQL_INI_SECTION, _SQL_INI_KEY, "",
dllname, _MAX_PATH, _SQL_INI_FILE ) != 0 ) {
i_get_dll_name( dllname, TRUE );
gotdll = i_load_dll( dllname, &wrongversion );
}
}
#endif
if( !gotdll ) { /* let the OS look for the DLL in the PATH */
dllname[0] = '\0';
i_get_dll_name( dllname, FALSE );
gotdll = i_load_dll( dllname, &wrongversion );
}
if( gotdll ) {
return( ESQLDLL_OK );
}
if( wrongversion ) {
return( ESQLDLL_WRONG_VERSION );
}
return( ESQLDLL_DLL_NOT_FOUND );
}
/*
** This function returns the HINSTANCE of the DBLib routine. This is
** required because some routines (in Sybase Central for example) make
** calls directly out of the dblib dll and consequently must dynamically
** find those routines (which requires the HINSTANCE).
**
** Returns
** HMODULE/HINSTANCE the hinstance of the dblib dll
*/
extern void *db_get_dblib_dll( void )
{
return (void *)dll_handle;
}