1/*************************************************
2 * SQLInstallDriverEx
3 *
4 * pnUsageCount UsageCount is incremented and decremented
5 * only in this lib. This is done whenever
6 * a request is made to install or remove
7 * a driver.
8 * This differs slightly from the MS spec.
9 * see UsageCount entries in odbcinst.ini
10 *
11 * pszPathOut This lacks some smarts. I will pass pszPathIn
12 * back here or, if pszPathIn=NULL, I will default
13 * to /usr/lib
14 *
15 **************************************************
16 * This code was created by Peter Harvey @ CodeByDesign.
17 * Released under LGPL 28.JAN.99
18 *
19 * Contributions from...
20 * -----------------------------------------------
21 * Peter Harvey - pharvey@codebydesign.com
22 **************************************************/
23#include <config.h>
24#include <odbcinstext.h>
25
26BOOL SQLInstallDriverEx( LPCSTR pszDriver,
27 LPCSTR pszPathIn,
28 LPSTR pszPathOut,
29 WORD nPathOutMax,
30 WORD *pnPathOut,
31 WORD nRequest,
32 LPDWORD pnUsageCount )
33{
34 HINI hIni;
35 char szObjectName[INI_MAX_OBJECT_NAME+1];
36 char szNameValue[INI_MAX_PROPERTY_NAME+INI_MAX_PROPERTY_VALUE+3];
37 char szPropertyName[INI_MAX_PROPERTY_NAME+1];
38 char szValue[INI_MAX_PROPERTY_VALUE+1];
39 char szIniName[ ODBC_FILENAME_MAX * 2 + 1 ];
40
41 BOOL bInsertUsageCount;
42 int nElement;
43 int nUsageCount = 0; /* SHOULD GET THIS FROM SOMEWHERE ? */
44 char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ];
45
46
47 inst_logClear();
48
49 /* SANITY CHECKS */
50 if ( pszDriver == NULL || pszPathOut == NULL )
51 {
52 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" );
53 return FALSE;
54 }
55 if ( nRequest != ODBC_INSTALL_INQUIRY && nRequest != ODBC_INSTALL_COMPLETE )
56 {
57 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_REQUEST_TYPE, "" );
58 return FALSE;
59 }
60
61 memset( pszPathOut, '\0', nPathOutMax );
62
63 if ( pszPathIn )
64 {
65#ifdef VMS
66 snprintf( szIniName, sizeof(szIniName), "%s:%s", pszPathIn, odbcinst_system_file_name( b2 ) );
67#else
68 snprintf( szIniName, sizeof(szIniName), "%s/%s", pszPathIn, odbcinst_system_file_name( b2 ) );
69#endif
70 }
71 else
72 {
73#ifdef VMS
74 sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) );
75#else
76 sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) );
77#endif
78 }
79
80 /* PROCESS ODBC INST INI FILE */
81
82#ifdef __OS2__
83 if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS )
84#else
85 if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS )
86#endif
87 {
88 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" );
89 return FALSE;
90 }
91
92 if ( iniElement( (char *)pszDriver, '\0', '\0', 0, szObjectName, INI_MAX_OBJECT_NAME ) != INI_SUCCESS )
93 {
94 iniClose( hIni );
95 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_KEYWORD_VALUE, "" );
96 return FALSE;
97 }
98
99 /* LETS GET ITS FILE USAGE VALUE (if any) */
100 if ( iniPropertySeek( hIni, szObjectName, "UsageCount", "" ) == INI_SUCCESS )
101 {
102 iniValue( hIni, szValue );
103 nUsageCount = atoi( szValue );
104 }
105
106 /* DOES THE OBJECT ALREADY EXIST? (also ensures that we have correct current object) */
107 if ( iniObjectSeek( hIni, szObjectName ) == INI_SUCCESS )
108 {
109 if ( nUsageCount == 0 )
110 nUsageCount = 1;
111
112 if ( nRequest == ODBC_INSTALL_COMPLETE )
113 {
114 iniObjectDelete( hIni );
115 }
116 }
117
118 /* LETS ADD THE SECTION AND ENTRY */
119 nUsageCount++;
120 if ( nRequest == ODBC_INSTALL_COMPLETE )
121 {
122 bInsertUsageCount = TRUE;
123 iniObjectInsert( hIni, szObjectName );
124 for ( nElement=1;
125 iniElement( (char *)pszDriver, '\0', '\0', nElement, szNameValue, INI_MAX_PROPERTY_NAME+INI_MAX_PROPERTY_VALUE+3 ) == INI_SUCCESS;
126 nElement++ )
127 {
128 iniElement( szNameValue, '=', '\0', 0, szPropertyName, INI_MAX_PROPERTY_NAME );
129 iniElementEOL( szNameValue, '=', '\0', 1, szValue, INI_MAX_PROPERTY_VALUE );
130 if ( szPropertyName[0] != '\0' )
131 {
132 /* OVERRIDE ANY USAGE COUNT CHANGES */
133 if ( strcasecmp( szPropertyName, "UsageCount" ) == 0 )
134 {
135 bInsertUsageCount = FALSE;
136 sprintf( szValue, "%d", nUsageCount );
137 }
138 iniPropertyInsert( hIni, szPropertyName, szValue );
139 }
140 else
141 {
142 iniClose( hIni );
143 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_KEYWORD_VALUE, "" );
144 return FALSE;
145 }
146 } /* for */
147
148 if ( bInsertUsageCount )
149 {
150 /* LETS INSERT USAGE COUNT */
151 sprintf( szValue, "%d", nUsageCount );
152 iniPropertyInsert( hIni, "UsageCount", szValue );
153 }
154
155 if ( iniCommit( hIni ) != INI_SUCCESS )
156 {
157 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_PATH, "" );
158 iniClose( hIni );
159 return FALSE;
160 }
161 }
162 iniClose( hIni );
163
164 /* OK, SO WHATS LEFT? */
165 if ( pszPathIn == NULL )
166 {
167 if ( pszPathOut )
168 {
169 if ( strlen( odbcinst_system_file_path( b1 )) < nPathOutMax )
170 {
171 strcpy( pszPathOut, odbcinst_system_file_path( b1 ));
172 }
173 else
174 {
175 strncpy( pszPathOut, odbcinst_system_file_path( b1 ), nPathOutMax );
176 pszPathOut[ nPathOutMax - 1 ] = '\0';
177 }
178 }
179 }
180 else
181 {
182 if ( pszPathOut )
183 {
184 if ( strlen( pszPathIn ) < nPathOutMax )
185 {
186 strcpy( pszPathOut, pszPathIn );
187 }
188 else
189 {
190 strncpy( pszPathOut, pszPathIn, nPathOutMax );
191 pszPathOut[ nPathOutMax - 1 ] = '\0';
192 }
193 }
194 }
195
196 if ( pnPathOut != NULL )
197 {
198 if ( pszPathIn == NULL )
199 {
200 *pnPathOut = strlen( odbcinst_system_file_path( b1 ));
201 }
202 else
203 {
204 *pnPathOut = strlen( pszPathIn );
205 }
206 }
207
208 if ( pnUsageCount != NULL )
209 {
210 *pnUsageCount = nUsageCount;
211 }
212
213 return TRUE;
214}
215
216BOOL INSTAPI SQLInstallDriverExW(LPCWSTR lpszDriver,
217 LPCWSTR lpszPathIn,
218 LPWSTR lpszPathOut,
219 WORD cbPathOutMax,
220 WORD *pcbPathOut,
221 WORD fRequest,
222 LPDWORD lpdwUsageCount)
223{
224 char *drv;
225 char *pth;
226 char *pout;
227 WORD len;
228 BOOL ret;
229
230 inst_logClear();
231
232 drv = lpszDriver ? _multi_string_alloc_and_copy( lpszDriver ) : (char*)NULL;
233 pth = lpszPathIn ? _single_string_alloc_and_copy( lpszPathIn ) : (char*)NULL;
234
235 if ( lpszPathOut )
236 {
237 if ( cbPathOutMax > 0 )
238 {
239 pout = calloc( cbPathOutMax + 1, 1 );
240 }
241 else
242 {
243 pout = NULL;
244 }
245 }
246 else
247 {
248 pout = NULL;
249 }
250
251 ret = SQLInstallDriverEx( drv, pth, pout, cbPathOutMax, &len, fRequest, lpdwUsageCount );
252
253 if ( ret )
254 {
255 if ( pout && lpszPathOut )
256 {
257 _single_copy_to_wide( lpszPathOut, pout, len + 1 );
258 }
259 }
260
261 if ( pcbPathOut )
262 {
263 *pcbPathOut = len;
264 }
265
266 if ( drv )
267 free( drv );
268 if ( pth )
269 free( pth );
270 if ( pout )
271 free( pout );
272
273 return ret;
274}
275