1 | /************************************************** |
2 | * SQLManageDataSources |
3 | * |
4 | ************************************************** |
5 | * This code was created by Peter Harvey @ CodeByDesign. |
6 | * Released under LGPL 28.JAN.99 |
7 | * |
8 | * Contributions from... |
9 | * ----------------------------------------------- |
10 | * Peter Harvey - pharvey@codebydesign.com |
11 | **************************************************/ |
12 | #include <config.h> |
13 | #include <odbcinstext.h> |
14 | |
15 | /*! |
16 | * \brief Get the short name of the UI plugin. |
17 | * |
18 | * The short name is the file name without path or file extension. |
19 | * |
20 | * We silently prepend "lib" here as well. |
21 | * |
22 | * \param pszName Place to put short name. Should be FILENAME_MAX bytes. |
23 | * \param pszUI Our generic window handle. |
24 | * |
25 | * \return char* pszName returned for convenience. |
26 | */ |
27 | char *_getUIPluginName( char *pszName, char *pszUI ) |
28 | { |
29 | *pszName = '\0'; |
30 | |
31 | /* is it being provided by caller? */ |
32 | if ( pszUI && *pszUI ) |
33 | { |
34 | sprintf( pszName, "lib%s" , pszUI ); |
35 | return pszName; |
36 | } |
37 | |
38 | /* is it being provided by env var? */ |
39 | { |
40 | char *pEnvVar = getenv( "ODBCINSTUI" ); |
41 | if ( pEnvVar ) |
42 | { |
43 | sprintf( pszName, "lib%s" , pEnvVar ); |
44 | return pszName; |
45 | } |
46 | } |
47 | |
48 | /* is it being provided by odbcinst.ini? */ |
49 | { |
50 | char sz[FILENAME_MAX]; |
51 | *sz='\0'; |
52 | SQLGetPrivateProfileString( "ODBC" , "ODBCINSTUI" , "" , sz, FILENAME_MAX, "odbcinst.ini" ); |
53 | if ( *sz ) |
54 | { |
55 | sprintf( pszName, "lib%s" , sz ); |
56 | return pszName; |
57 | } |
58 | } |
59 | |
60 | /* default to qt4 */ |
61 | strcpy( pszName, "libodbcinstQ4" ); |
62 | |
63 | return pszName; |
64 | } |
65 | |
66 | /*! |
67 | * \brief Append the file extension used by the OS for plugins. |
68 | * |
69 | * We use SHLIBEXT which is picked up at configure/build time. |
70 | * |
71 | * \param pszNameAndExtension Output. Needs to be FILENAME_MAX bytes. |
72 | * \param pszName Input. |
73 | * |
74 | * \return char* pszNameAndExtension returned for convenience. |
75 | */ |
76 | char *_appendUIPluginExtension( char *pszNameAndExtension, char *pszName ) |
77 | { |
78 | if ( strlen( SHLIBEXT ) > 0 ) |
79 | sprintf( pszNameAndExtension, "%s%s" , pszName, SHLIBEXT ); |
80 | else |
81 | sprintf( pszNameAndExtension, "%s.so" , pszName ); |
82 | |
83 | return pszName; |
84 | } |
85 | |
86 | /*! |
87 | * \brief Prepends the path used for the plugins. |
88 | * |
89 | * We use DEFLIB_PATH and if it is not available... |
90 | * path may not get prepended. |
91 | * |
92 | * \param pszPathAndName Output. Needs to be FILENAME_MAX bytes. |
93 | * \param pszName Input. |
94 | * |
95 | * \return char* pszPathAndName is returned for convenience. |
96 | */ |
97 | char *_prependUIPluginPath( char *pszPathAndName, char *pszName ) |
98 | { |
99 | if ( strlen( DEFLIB_PATH ) > 0 ) |
100 | sprintf( pszPathAndName, "%s/%s" , DEFLIB_PATH, pszName ); |
101 | else |
102 | sprintf( pszPathAndName, "%s" , pszName ); |
103 | |
104 | return pszPathAndName; |
105 | } |
106 | |
107 | /*! |
108 | * \brief UI to manage most ODBC system information. |
109 | * |
110 | * This calls into the UI plugin library to do our work for us. The caller can provide |
111 | * the name (base name) of the library or let us determine which library to use. |
112 | * See \sa _getUIPluginName for details on how the choice is made. |
113 | * |
114 | * \param hWnd Input. Parent window handle. This is HWND as per the ODBC |
115 | * specification but in unixODBC we use a generic window |
116 | * handle. Caller must cast a HODBCINSTWND to HWND at call. |
117 | * |
118 | * \return BOOL |
119 | * |
120 | * \sa ODBCINSTWND |
121 | */ |
122 | BOOL SQLManageDataSources( HWND hWnd ) |
123 | { |
124 | HODBCINSTWND hODBCInstWnd = (HODBCINSTWND)hWnd; |
125 | char szName[FILENAME_MAX]; |
126 | char szNameAndExtension[FILENAME_MAX]; |
127 | char szPathAndName[FILENAME_MAX]; |
128 | void * hDLL; |
129 | BOOL (*pSQLManageDataSources)(HWND); |
130 | |
131 | inst_logClear(); |
132 | |
133 | /* ODBC specification states that hWnd is mandatory. */ |
134 | if ( !hWnd ) |
135 | { |
136 | inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_HWND, "No hWnd" ); |
137 | return FALSE; |
138 | } |
139 | |
140 | /* initialize libtool */ |
141 | if ( lt_dlinit() ) |
142 | { |
143 | inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "lt_dlinit() failed" ); |
144 | return FALSE; |
145 | } |
146 | |
147 | /* get plugin name */ |
148 | _appendUIPluginExtension( szNameAndExtension, _getUIPluginName( szName, hODBCInstWnd->szUI ) ); |
149 | |
150 | /* lets try loading the plugin using an implicit path */ |
151 | hDLL = lt_dlopen( szNameAndExtension ); |
152 | if ( hDLL ) |
153 | { |
154 | /* change the name (SQLManageDataSources to ODBCManageDataSources) to prevent us from calling ourself */ |
155 | pSQLManageDataSources = (BOOL (*)(HWND))lt_dlsym( hDLL, "ODBCManageDataSources" ); |
156 | if ( pSQLManageDataSources ) |
157 | return pSQLManageDataSources( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ) ); |
158 | else |
159 | inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); |
160 | } |
161 | else |
162 | { |
163 | inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_WARNING, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); |
164 | /* try with explicit path */ |
165 | _prependUIPluginPath( szPathAndName, szNameAndExtension ); |
166 | hDLL = lt_dlopen( szPathAndName ); |
167 | if ( hDLL ) |
168 | { |
169 | /* change the name (SQLManageDataSources to ODBCManageDataSources) to prevent us from calling ourself */ |
170 | /* its only safe to use hWnd if szUI was specified by the caller */ |
171 | pSQLManageDataSources = (BOOL (*)(HWND))lt_dlsym( hDLL, "ODBCManageDataSources" ); |
172 | if ( pSQLManageDataSources ) |
173 | return pSQLManageDataSources( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ) ); |
174 | else |
175 | inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); |
176 | } |
177 | else |
178 | inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); |
179 | } |
180 | |
181 | /* report failure to caller */ |
182 | inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Failed to load/use a UI plugin." ); |
183 | |
184 | return FALSE; |
185 | } |
186 | |
187 | |
188 | |