1/**************************************************
2 * SQLCreateDataSource
3 *
4 * This is a 100% UI so simply pass it on to odbcinst's UI
5 * shadow share.
6 *
7 **************************************************
8 * This code was created by Peter Harvey @ CodeByDesign.
9 * Released under LGPL 28.JAN.99
10 *
11 * Contributions from...
12 * -----------------------------------------------
13 * Peter Harvey - pharvey@codebydesign.com
14 **************************************************/
15#include <config.h>
16#include <odbcinstext.h>
17
18/*
19 * Take a wide string consisting of null terminated sections, and copy to a ASCII version
20 */
21
22char* _multi_string_alloc_and_copy( LPCWSTR in )
23{
24 char *chr;
25 int len = 0;
26
27 if ( !in )
28 {
29 return NULL;
30 }
31
32 while ( in[ len ] != 0 || in[ len + 1 ] != 0 )
33 {
34 len ++;
35 }
36
37 chr = malloc( len + 2 );
38
39 len = 0;
40 while ( in[ len ] != 0 || in[ len + 1 ] != 0 )
41 {
42 chr[ len ] = 0xFF & in[ len ];
43 len ++;
44 }
45 chr[ len ++ ] = '\0';
46 chr[ len ++ ] = '\0';
47
48 return chr;
49}
50
51char* _single_string_alloc_and_copy( LPCWSTR in )
52{
53 char *chr;
54 int len = 0;
55
56 if ( !in )
57 {
58 return NULL;
59 }
60
61 while ( in[ len ] != 0 )
62 {
63 len ++;
64 }
65
66 chr = malloc( len + 1 );
67
68 len = 0;
69 while ( in[ len ] != 0 )
70 {
71 chr[ len ] = 0xFF & in[ len ];
72 len ++;
73 }
74 chr[ len ++ ] = '\0';
75
76 return chr;
77}
78
79SQLWCHAR* _multi_string_alloc_and_expand( LPCSTR in )
80{
81 SQLWCHAR *chr;
82 int len = 0;
83
84 if ( !in )
85 {
86 return NULL;
87 }
88
89 while ( in[ len ] != 0 || in[ len + 1 ] != 0 )
90 {
91 len ++;
92 }
93
94 chr = malloc(sizeof( SQLWCHAR ) * ( len + 2 ));
95
96 len = 0;
97 while ( in[ len ] != 0 || in[ len + 1 ] != 0 )
98 {
99 chr[ len ] = in[ len ];
100 len ++;
101 }
102 chr[ len ++ ] = 0;
103 chr[ len ++ ] = 0;
104
105 return chr;
106}
107
108SQLWCHAR* _single_string_alloc_and_expand( LPCSTR in )
109{
110 SQLWCHAR *chr;
111 int len = 0;
112
113 if ( !in )
114 {
115 return NULL;
116 }
117
118 while ( in[ len ] != 0 )
119 {
120 len ++;
121 }
122
123 chr = malloc( sizeof( SQLWCHAR ) * ( len + 1 ));
124
125 len = 0;
126 while ( in[ len ] != 0 )
127 {
128 chr[ len ] = in[ len ];
129 len ++;
130 }
131 chr[ len ++ ] = 0;
132
133 return chr;
134}
135
136void _single_string_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len )
137{
138 while ( len > 0 && *in )
139 {
140 *out = *in;
141 out++;
142 in++;
143 len --;
144 }
145 *out = 0;
146}
147
148void _single_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len )
149{
150 while ( len >= 0 )
151 {
152 *out = *in;
153 out++;
154 in++;
155 len --;
156 }
157}
158
159void _single_copy_from_wide( SQLCHAR *out, LPCWSTR in, int len )
160{
161 while ( len >= 0 )
162 {
163 *out = *in;
164 out++;
165 in++;
166 len --;
167 }
168}
169
170void _multi_string_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len )
171{
172 while ( len > 0 && ( in[ 0 ] || in[ 1 ] ))
173 {
174 *out = *in;
175 out++;
176 in++;
177 len --;
178 }
179 *out++ = 0;
180 *out++ = 0;
181}
182
183/*!
184 * \brief Invokes a UI (a wizard) to walk User through creating a DSN.
185 *
186 * \param hWnd Input. Parent window handle. This is HWND as per the ODBC
187 * specification but in unixODBC we use a generic window
188 * handle. Caller must cast a HODBCINSTWND to HWND at call.
189 * \param pszDS Input. Data Source Name. This can be a NULL pointer.
190 *
191 * \return BOOL
192 *
193 * \sa ODBCINSTWND
194 */
195BOOL SQLCreateDataSource( HWND hWnd, LPCSTR pszDS )
196{
197 HODBCINSTWND hODBCInstWnd = (HODBCINSTWND)hWnd;
198 char szName[FILENAME_MAX];
199 char szNameAndExtension[FILENAME_MAX];
200 char szPathAndName[FILENAME_MAX];
201 void * hDLL;
202 BOOL (*pSQLCreateDataSource)(HWND, LPCSTR);
203
204 inst_logClear();
205
206 /* ODBC specification states that hWnd is mandatory. */
207 if ( !hWnd )
208 {
209 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_HWND, "" );
210 return FALSE;
211 }
212
213 /* initialize libtool */
214 if ( lt_dlinit() )
215 {
216 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "lt_dlinit() failed" );
217 return FALSE;
218 }
219
220 /* get plugin name */
221 _appendUIPluginExtension( szNameAndExtension, _getUIPluginName( szName, hODBCInstWnd->szUI ) );
222
223 /* lets try loading the plugin using an implicit path */
224 hDLL = lt_dlopen( szNameAndExtension );
225 if ( hDLL )
226 {
227 /* change the name, as it avoids it finding it in the calling lib */
228 pSQLCreateDataSource = (BOOL (*)(HWND, LPCSTR))lt_dlsym( hDLL, "ODBCCreateDataSource" );
229 if ( pSQLCreateDataSource )
230 return pSQLCreateDataSource( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ), pszDS );
231 else
232 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() );
233 }
234 else
235 {
236 /* try with explicit path */
237 _prependUIPluginPath( szPathAndName, szNameAndExtension );
238 hDLL = lt_dlopen( szPathAndName );
239 if ( hDLL )
240 {
241 /* change the name, as it avoids linker finding it in the calling lib */
242 pSQLCreateDataSource = (BOOL (*)(HWND,LPCSTR))lt_dlsym( hDLL, "ODBCCreateDataSource" );
243 if ( pSQLCreateDataSource )
244 return pSQLCreateDataSource( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ), pszDS );
245 else
246 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() );
247 }
248 }
249
250 /* report failure to caller */
251 inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" );
252
253 return FALSE;
254}
255
256/*!
257 * \brief A wide char version of \sa SQLCreateDataSource.
258 *
259 * \sa SQLCreateDataSource
260 */
261BOOL INSTAPI SQLCreateDataSourceW( HWND hwndParent, LPCWSTR lpszDSN )
262{
263 BOOL ret;
264 char *ms = _multi_string_alloc_and_copy( lpszDSN );
265
266 inst_logClear();
267
268 ret = SQLCreateDataSource( hwndParent, ms );
269
270 free( ms );
271
272 return ret;
273}
274
275