drvconn.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. /*
  2. * drvconn.c
  3. *
  4. * $Id$
  5. *
  6. * The data_sources dialog for SQLDriverConnect
  7. *
  8. * The iODBC driver manager.
  9. *
  10. * Copyright (C) 1996-2021 OpenLink Software <[email protected]>
  11. * All Rights Reserved.
  12. *
  13. * This software is released under the terms of either of the following
  14. * licenses:
  15. *
  16. * - GNU Library General Public License (see LICENSE.LGPL)
  17. * - The BSD License (see LICENSE.BSD).
  18. *
  19. * Note that the only valid version of the LGPL license as far as this
  20. * project is concerned is the original GNU Library General Public License
  21. * Version 2, dated June 1991.
  22. *
  23. * While not mandated by the BSD license, any patches you make to the
  24. * iODBC source code may be contributed back into the iODBC project
  25. * at your discretion. Contributions will benefit the Open Source and
  26. * Data Access community as a whole. Submissions may be made at:
  27. *
  28. * http://www.iodbc.org
  29. *
  30. *
  31. * GNU Library Generic Public License Version 2
  32. * ============================================
  33. * This library is free software; you can redistribute it and/or
  34. * modify it under the terms of the GNU Library General Public
  35. * License as published by the Free Software Foundation; only
  36. * Version 2 of the License dated June 1991.
  37. *
  38. * This library is distributed in the hope that it will be useful,
  39. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  40. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  41. * Library General Public License for more details.
  42. *
  43. * You should have received a copy of the GNU Library General Public
  44. * License along with this library; if not, write to the Free
  45. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  46. *
  47. *
  48. * The BSD License
  49. * ===============
  50. * Redistribution and use in source and binary forms, with or without
  51. * modification, are permitted provided that the following conditions
  52. * are met:
  53. *
  54. * 1. Redistributions of source code must retain the above copyright
  55. * notice, this list of conditions and the following disclaimer.
  56. * 2. Redistributions in binary form must reproduce the above copyright
  57. * notice, this list of conditions and the following disclaimer in
  58. * the documentation and/or other materials provided with the
  59. * distribution.
  60. * 3. Neither the name of OpenLink Software Inc. nor the names of its
  61. * contributors may be used to endorse or promote products derived
  62. * from this software without specific prior written permission.
  63. *
  64. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  65. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  66. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  67. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR
  68. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  69. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  70. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  71. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  72. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  73. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  74. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75. */
  76. #include "gui.h"
  77. #include "herr.h"
  78. #include "unicode.h"
  79. #include "dlproc.h"
  80. #ifndef WIN32
  81. #include <unistd.h>
  82. typedef SQLRETURN SQL_API (*pDriverConnFunc) (HWND hwnd, LPSTR szInOutConnStr,
  83. DWORD cbInOutConnStr, int FAR * sqlStat, SQLUSMALLINT fDriverCompletion, UWORD *config);
  84. typedef SQLRETURN SQL_API (*pDriverConnWFunc) (HWND hwnd, LPWSTR szInOutConnStr,
  85. DWORD cbInOutConnStr, int FAR * sqlStat, SQLUSMALLINT fDriverCompletion, UWORD *config);
  86. #if defined (__APPLE__)
  87. #define CALL_DRVCONN_DIALBOXW(path, a) \
  88. if (path) \
  89. { \
  90. char *_path_u8 = (a == 'A') ? strdup((const char *)path) : (char*)dm_SQL_W2A ((wchar_t*)path, SQL_NTS); \
  91. if (_path_u8) { \
  92. char *ptr = strstr(_path_u8, "/Contents/MacOS/"); \
  93. if (ptr) \
  94. *ptr = 0; \
  95. liburl = CFURLCreateFromFileSystemRepresentation (NULL, (UInt8*)_path_u8, strlen(_path_u8), FALSE); \
  96. CFArrayRef arr = CFBundleCopyExecutableArchitecturesForURL(liburl); \
  97. if (arr) \
  98. bundle_dll = CFBundleCreate (NULL, liburl); \
  99. if (arr) \
  100. CFRelease(arr); \
  101. if (liburl) \
  102. CFRelease(liburl); \
  103. } \
  104. MEM_FREE(_path_u8); \
  105. CALL_DRVCONN_DIALBOXW_BUNDLE(); \
  106. }
  107. #define CALL_DRVCONN_DIALBOXW_BUNDLE() \
  108. if (bundle_dll != NULL) \
  109. { \
  110. if ((pDrvConnW = (pDriverConnWFunc)CFBundleGetFunctionPointerForName(bundle_dll, CFSTR("_iodbcdm_drvconn_dialboxw"))) != NULL) \
  111. { \
  112. SQLSetConfigMode (*config); \
  113. if (pDrvConnW (hwnd, szInOutConnStr, cbInOutConnStr, sqlStat, fDriverCompletion, config) == SQL_SUCCESS) \
  114. { \
  115. retcode = SQL_SUCCESS; \
  116. goto quit; \
  117. } \
  118. else \
  119. { \
  120. retcode = SQL_NO_DATA_FOUND; \
  121. goto quit; \
  122. } \
  123. } \
  124. else \
  125. { \
  126. if ((pDrvConn = (pDriverConnFunc)CFBundleGetFunctionPointerForName(bundle_dll, CFSTR("_iodbcdm_drvconn_dialbox"))) != NULL) \
  127. { \
  128. char *_szinoutconstr_u8 = malloc (cbInOutConnStr + 1); \
  129. wchar_t *_prvw; char *_prvu8; \
  130. for (_prvw = szInOutConnStr, _prvu8 = _szinoutconstr_u8 ; \
  131. *_prvw != L'\0' ; _prvw += WCSLEN (_prvw) + 1, \
  132. _prvu8 += STRLEN (_prvu8) + 1) \
  133. dm_StrCopyOut2_W2A (_prvw, (SQLCHAR *)_prvu8, cbInOutConnStr, NULL); \
  134. *_prvu8 = '\0'; \
  135. SQLSetConfigMode (*config); \
  136. if (pDrvConn (hwnd, _szinoutconstr_u8, cbInOutConnStr, sqlStat, fDriverCompletion, config) == SQL_SUCCESS) \
  137. { \
  138. dm_StrCopyOut2_A2W ((SQLCHAR *)_szinoutconstr_u8, szInOutConnStr, cbInOutConnStr, NULL); \
  139. MEM_FREE (_szinoutconstr_u8); \
  140. retcode = SQL_SUCCESS; \
  141. goto quit; \
  142. } \
  143. else \
  144. { \
  145. MEM_FREE (_szinoutconstr_u8); \
  146. retcode = SQL_NO_DATA_FOUND; \
  147. goto quit; \
  148. } \
  149. } \
  150. } \
  151. }
  152. #else
  153. #define CALL_DRVCONN_DIALBOXW(path, a) \
  154. { \
  155. char *_path_u8 = (a == 'A') ? NULL : dm_SQL_W2A ((wchar_t*)path, SQL_NTS); \
  156. if ((handle = DLL_OPEN((a == 'A') ? (char*)path : _path_u8)) != NULL) \
  157. { \
  158. if ((pDrvConnW = (pDriverConnWFunc)DLL_PROC(handle, "_iodbcdm_drvconn_dialboxw")) != NULL) \
  159. { \
  160. SQLSetConfigMode (*config); \
  161. if (pDrvConnW (hwnd, szInOutConnStr, cbInOutConnStr, sqlStat, fDriverCompletion, config) == SQL_SUCCESS) \
  162. { \
  163. MEM_FREE (_path_u8); \
  164. DLL_CLOSE(handle); \
  165. retcode = SQL_SUCCESS; \
  166. goto quit; \
  167. } \
  168. else \
  169. { \
  170. MEM_FREE (_path_u8); \
  171. DLL_CLOSE(handle); \
  172. retcode = SQL_NO_DATA_FOUND; \
  173. goto quit; \
  174. } \
  175. } \
  176. else \
  177. { \
  178. if ((pDrvConn = (pDriverConnFunc)DLL_PROC(handle, "_iodbcdm_drvconn_dialbox")) != NULL) \
  179. { \
  180. char *_szinoutconstr_u8 = malloc (cbInOutConnStr + 1); \
  181. wchar_t *_prvw; char *_prvu8; \
  182. for (_prvw = szInOutConnStr, _prvu8 = _szinoutconstr_u8 ; \
  183. *_prvw != L'\0' ; _prvw += WCSLEN (_prvw) + 1, \
  184. _prvu8 += STRLEN (_prvu8) + 1) \
  185. dm_StrCopyOut2_W2A (_prvw, _prvu8, cbInOutConnStr, NULL); \
  186. *_prvu8 = '\0'; \
  187. SQLSetConfigMode (*config); \
  188. if (pDrvConn (hwnd, _szinoutconstr_u8, cbInOutConnStr, sqlStat, fDriverCompletion, config) == SQL_SUCCESS) \
  189. { \
  190. dm_StrCopyOut2_A2W (_szinoutconstr_u8, szInOutConnStr, cbInOutConnStr, NULL); \
  191. MEM_FREE (_path_u8); \
  192. MEM_FREE (_szinoutconstr_u8); \
  193. DLL_CLOSE(handle); \
  194. retcode = SQL_SUCCESS; \
  195. goto quit; \
  196. } \
  197. else \
  198. { \
  199. MEM_FREE (_path_u8); \
  200. MEM_FREE (_szinoutconstr_u8); \
  201. DLL_CLOSE(handle); \
  202. retcode = SQL_NO_DATA_FOUND; \
  203. goto quit; \
  204. } \
  205. } \
  206. } \
  207. DLL_CLOSE(handle); \
  208. } \
  209. MEM_FREE (_path_u8); \
  210. }
  211. #endif
  212. #endif
  213. SQLRETURN SQL_API
  214. iodbcdm_drvconn_dialbox (
  215. HWND hwnd,
  216. LPSTR szInOutConnStr,
  217. DWORD cbInOutConnStr,
  218. int * sqlStat,
  219. SQLUSMALLINT fDriverCompletion,
  220. UWORD *config)
  221. {
  222. RETCODE retcode = SQL_ERROR;
  223. wchar_t *_string_w = NULL;
  224. if (cbInOutConnStr > 0)
  225. {
  226. if ((_string_w = malloc (cbInOutConnStr * sizeof(wchar_t) + 1)) == NULL)
  227. goto done;
  228. }
  229. dm_StrCopyOut2_A2W ((SQLCHAR*)szInOutConnStr, _string_w,
  230. cbInOutConnStr * sizeof(wchar_t), NULL);
  231. retcode = iodbcdm_drvconn_dialboxw (hwnd, _string_w,
  232. cbInOutConnStr, sqlStat, fDriverCompletion, config);
  233. if (retcode == SQL_SUCCESS)
  234. {
  235. dm_StrCopyOut2_W2A (_string_w, (SQLCHAR*)szInOutConnStr, cbInOutConnStr - 1, NULL);
  236. }
  237. done:
  238. MEM_FREE (_string_w);
  239. return retcode;
  240. }
  241. SQLRETURN SQL_API
  242. iodbcdm_drvconn_dialboxw (
  243. HWND hwnd,
  244. LPWSTR szInOutConnStr,
  245. DWORD cbInOutConnStr,
  246. int * sqlStat,
  247. SQLUSMALLINT fDriverCompletion,
  248. UWORD *config)
  249. {
  250. RETCODE retcode = SQL_ERROR;
  251. TDSNCHOOSER choose_t;
  252. wchar_t *string = NULL, *prov, *prov1, *szDSN = NULL, *szDriver = NULL;
  253. wchar_t *szFILEDSN = NULL, *szSAVEFILE = NULL;
  254. wchar_t tokenstr[4096];
  255. wchar_t drvbuf[4096] = { L'\0'};
  256. char *_szdriver_u8 = NULL;
  257. wchar_t *_szdriver_w = NULL;
  258. HDLL handle;
  259. pDriverConnFunc pDrvConn;
  260. pDriverConnWFunc pDrvConnW;
  261. int i, skip;
  262. #if defined (__APPLE__) && !defined (NO_FRAMEWORKS)
  263. CFBundleRef bundle = NULL;
  264. CFBundleRef bundle_dll = NULL;
  265. CFURLRef liburl = NULL;
  266. #endif
  267. memset(&choose_t, 0, sizeof(choose_t));
  268. /* Check input parameters */
  269. if (!szInOutConnStr || cbInOutConnStr < 1)
  270. goto quit;
  271. /* Transform the string connection to list of key pairs */
  272. string = (wchar_t*) malloc((cbInOutConnStr + 1) * sizeof(wchar_t));
  273. if (string == NULL)
  274. {
  275. if (sqlStat)
  276. #if (ODBCVER>=0x3000)
  277. *sqlStat = en_HY092;
  278. #else
  279. *sqlStat = en_S1000;
  280. #endif
  281. retcode = SQL_ERROR;
  282. goto quit;
  283. }
  284. /* Conversion to the list of key pairs */
  285. wcsncpy (string, szInOutConnStr, cbInOutConnStr);
  286. string[WCSLEN (string) + 1] = L'\0';
  287. skip = 0;
  288. for (i = WCSLEN (string) - 1 ; i >= 0 ; i--)
  289. {
  290. if (string[i] == L'}')
  291. skip = 1;
  292. else if (string[i] == L'{')
  293. skip = 0;
  294. else if (skip == 0 && string[i] == L';') string[i] = L'\0';
  295. }
  296. /* Look for the DSN and DRIVER keyword */
  297. for (prov = string ; *prov != L'\0' ; prov += WCSLEN (prov) + 1)
  298. {
  299. if (!wcsncasecmp (prov, L"DSN=", WCSLEN (L"DSN=")))
  300. {
  301. szDSN = prov + WCSLEN (L"DSN=");
  302. continue;
  303. }
  304. if (!wcsncasecmp (prov, L"DRIVER=", WCSLEN (L"DRIVER=")))
  305. {
  306. szDriver = prov + WCSLEN (L"DRIVER=");
  307. continue;
  308. }
  309. if (!wcsncasecmp (prov, L"FILEDSN=", WCSLEN (L"FILEDSN=")))
  310. {
  311. szFILEDSN = prov + WCSLEN (L"FILEDSN=");
  312. continue;
  313. }
  314. if (!wcsncasecmp (prov, L"SAVEFILE=", WCSLEN (L"SAVEFILE=")))
  315. {
  316. szSAVEFILE = prov + WCSLEN (L"SAVEFILE=");
  317. continue;
  318. }
  319. }
  320. if (!szDSN && !szDriver)
  321. {
  322. /* Initialize members in case of early create_dsnchooser return */
  323. choose_t.dsn = NULL;
  324. choose_t.fdsn = NULL;
  325. /* Display the DSN chooser dialog box */
  326. create_dsnchooser (hwnd, &choose_t);
  327. /* Check output parameters */
  328. if (choose_t.dsn || choose_t.fdsn)
  329. {
  330. #if (ODBCVER>=0x3000)
  331. int errSqlStat = en_HY092;
  332. #else
  333. int errSqlStat = en_HY092;
  334. #endif
  335. /* Change the config mode */
  336. switch (choose_t.type_dsn)
  337. {
  338. case USER_DSN:
  339. *config = ODBC_USER_DSN;
  340. break;
  341. case SYSTEM_DSN:
  342. *config = ODBC_SYSTEM_DSN;
  343. break;
  344. };
  345. if (choose_t.dsn && (choose_t.type_dsn == USER_DSN || choose_t.type_dsn == SYSTEM_DSN))
  346. {
  347. /* Try to copy the DSN */
  348. if (cbInOutConnStr > WCSLEN (choose_t.dsn) + WCSLEN (L"DSN=") + 2)
  349. {
  350. WCSCPY (string, L"DSN=");
  351. WCSCAT (string, choose_t.dsn);
  352. string[WCSLEN (string) + 1] = L'\0';
  353. szDSN = string + WCSLEN (L"DSN=");
  354. retcode = SQL_SUCCESS;
  355. }
  356. else
  357. {
  358. if (sqlStat)
  359. *sqlStat = errSqlStat;
  360. }
  361. }
  362. else if (choose_t.fdsn && choose_t.type_dsn == FILE_DSN)
  363. {
  364. DWORD sz, sz_entry;
  365. wchar_t entries[4096];
  366. WORD read_len;
  367. wchar_t *p, *p_next;
  368. sz = WCSLEN(choose_t.fdsn) + WCSLEN(L"FILEDSN=") + 2;
  369. if (cbInOutConnStr > sz)
  370. {
  371. WCSCPY (string, L"FILEDSN=");
  372. WCSCAT (string, choose_t.fdsn);
  373. WCSCAT (string, L";");
  374. retcode = SQL_SUCCESS;
  375. }
  376. /* Get list of entries in .dsn file */
  377. if (retcode == SQL_SUCCESS
  378. && SQLReadFileDSNW (choose_t.fdsn, L"ODBC", NULL,
  379. entries, sizeof (entries)/sizeof(wchar_t), &read_len))
  380. {
  381. /* add params from the .dsn file */
  382. for (p = entries; *p != '\0'; p = p_next)
  383. {
  384. wchar_t value[1024];
  385. /* get next entry */
  386. p_next = wcschr (p, L';');
  387. if (p_next)
  388. *p_next++ = L'\0';
  389. if (!SQLReadFileDSNW (choose_t.fdsn, L"ODBC", p, value,
  390. sizeof(value)/sizeof(wchar_t), &read_len))
  391. {
  392. retcode = SQL_ERROR;
  393. break;
  394. }
  395. if (!wcsncasecmp (p, L"DRIVER", WCSLEN(L"DRIVER")))
  396. {
  397. szDriver = _szdriver_w = (wchar_t*) malloc((WCSLEN(value) + 1) * sizeof(wchar_t));
  398. if (szDriver)
  399. WCSCPY(szDriver, value);
  400. }
  401. sz_entry = WCSLEN(p) + 1 + WCSLEN(value) + 2;
  402. if (cbInOutConnStr > sz + sz_entry)
  403. {
  404. WCSCAT (string, p);
  405. WCSCAT (string, L"=");
  406. WCSCAT (string, value);
  407. WCSCAT (string, L";");
  408. sz += sz_entry;
  409. }
  410. else
  411. {
  412. retcode = SQL_ERROR;
  413. }
  414. }
  415. }
  416. if (retcode == SQL_SUCCESS)
  417. {
  418. string[WCSLEN (string) + 1] = L'\0';
  419. for (i = WCSLEN (string) - 1 ; i >= 0 ; i--)
  420. if (string[i] == L';') string[i] = L'\0';
  421. }
  422. else if (sqlStat)
  423. *sqlStat = errSqlStat;
  424. }
  425. else
  426. {
  427. if (sqlStat)
  428. *sqlStat = errSqlStat;
  429. }
  430. }
  431. else
  432. retcode = SQL_NO_DATA_FOUND;
  433. if (choose_t.dsn)
  434. free (choose_t.dsn);
  435. if (choose_t.fdsn)
  436. free (choose_t.fdsn);
  437. if (retcode != SQL_SUCCESS)
  438. goto quit;
  439. }
  440. /* Constitute the string connection */
  441. for (prov = szInOutConnStr, prov1 = string, i = 0 ; *prov1 != L'\0' ;
  442. prov1 += WCSLEN (prov) + 1, i += WCSLEN (prov) + 1, prov += WCSLEN (prov) + 1)
  443. WCSCPY (prov, prov1);
  444. *prov = L'\0';
  445. /* Check if the driver is provided */
  446. if (szDriver == NULL)
  447. {
  448. SQLSetConfigMode (ODBC_BOTH_DSN);
  449. SQLGetPrivateProfileStringW (L"ODBC Data Sources",
  450. szDSN && szDSN[0] != L'\0' ? szDSN : L"default",
  451. L"", tokenstr, sizeof (tokenstr)/sizeof(wchar_t), NULL);
  452. szDriver = tokenstr;
  453. }
  454. /* Call the iodbcdm_drvconn_dialbox */
  455. _szdriver_u8 = (char *)dm_SQL_W2A (szDriver, SQL_NTS);
  456. SQLSetConfigMode (ODBC_USER_DSN);
  457. if (!access (_szdriver_u8, X_OK))
  458. { CALL_DRVCONN_DIALBOXW (_szdriver_u8, 'A'); }
  459. if (SQLGetPrivateProfileStringW (szDriver, L"Driver", L"", drvbuf,
  460. sizeof (drvbuf) / sizeof(wchar_t), L"odbcinst.ini"))
  461. { CALL_DRVCONN_DIALBOXW (drvbuf, 'W'); }
  462. if (SQLGetPrivateProfileStringW (szDriver, L"Setup", L"", drvbuf,
  463. sizeof (drvbuf) / sizeof(wchar_t), L"odbcinst.ini"))
  464. { CALL_DRVCONN_DIALBOXW (drvbuf, 'W'); }
  465. if (SQLGetPrivateProfileStringW (L"Default", L"Driver", L"", drvbuf,
  466. sizeof (drvbuf) / sizeof(wchar_t), L"odbcinst.ini"))
  467. { CALL_DRVCONN_DIALBOXW (drvbuf, 'W'); }
  468. if (SQLGetPrivateProfileStringW (L"Default", L"Setup", L"", drvbuf,
  469. sizeof (drvbuf) / sizeof(wchar_t), L"odbcinst.ini"))
  470. { CALL_DRVCONN_DIALBOXW (drvbuf, 'W'); }
  471. SQLSetConfigMode (ODBC_SYSTEM_DSN);
  472. if (!access (_szdriver_u8, X_OK))
  473. { CALL_DRVCONN_DIALBOXW (_szdriver_u8, 'A'); }
  474. if (SQLGetPrivateProfileStringW (szDriver, L"Driver", L"", drvbuf,
  475. sizeof (drvbuf) / sizeof(wchar_t), L"odbcinst.ini"))
  476. { CALL_DRVCONN_DIALBOXW (drvbuf, 'W'); }
  477. if (SQLGetPrivateProfileStringW (szDriver, L"Setup", L"", drvbuf,
  478. sizeof (drvbuf) / sizeof(wchar_t), L"odbcinst.ini"))
  479. { CALL_DRVCONN_DIALBOXW (drvbuf, 'W'); }
  480. if (SQLGetPrivateProfileStringW (L"Default", L"Driver", L"", drvbuf,
  481. sizeof (drvbuf) / sizeof(wchar_t), L"odbcinst.ini"))
  482. { CALL_DRVCONN_DIALBOXW (drvbuf, 'W'); }
  483. if (SQLGetPrivateProfileStringW (L"Default", L"Setup", L"", drvbuf,
  484. sizeof (drvbuf) / sizeof(wchar_t), L"odbcinst.ini"))
  485. { CALL_DRVCONN_DIALBOXW (drvbuf, 'W'); }
  486. /* The last ressort, a proxy driver */
  487. #if defined (__APPLE__)
  488. # if !defined(NO_FRAMEWORKS)
  489. bundle = CFBundleGetBundleWithIdentifier (CFSTR ("org.iodbc.core"));
  490. if (bundle)
  491. {
  492. /* Search for the drvproxy library */
  493. liburl =
  494. CFBundleCopyResourceURL (bundle, CFSTR ("iODBCdrvproxy.bundle"),
  495. NULL, NULL);
  496. if (liburl)
  497. {
  498. bundle_dll = CFBundleCreate (NULL, liburl);
  499. CFRelease(liburl);
  500. CALL_DRVCONN_DIALBOXW_BUNDLE();
  501. }
  502. }
  503. # endif
  504. #else
  505. CALL_DRVCONN_DIALBOXW ("libdrvproxy.so.2", 'A');
  506. #endif
  507. if (sqlStat)
  508. *sqlStat = en_IM003;
  509. quit:
  510. MEM_FREE (string);
  511. MEM_FREE (_szdriver_u8);
  512. MEM_FREE (_szdriver_w);
  513. return retcode;
  514. }
  515. SQLRETURN SQL_API
  516. _iodbcdm_drvchoose_dialbox (
  517. HWND hwnd,
  518. LPSTR szInOutConnStr,
  519. DWORD cbInOutConnStr,
  520. int * sqlStat)
  521. {
  522. RETCODE retcode = SQL_ERROR;
  523. wchar_t *_string_w = NULL;
  524. WORD len;
  525. if (cbInOutConnStr > 0)
  526. {
  527. if ((_string_w = malloc ((cbInOutConnStr + 1) * sizeof(wchar_t))) == NULL)
  528. goto done;
  529. }
  530. retcode = _iodbcdm_drvchoose_dialboxw (hwnd, _string_w,
  531. cbInOutConnStr * sizeof(wchar_t), sqlStat);
  532. if (retcode == SQL_SUCCESS)
  533. {
  534. dm_StrCopyOut2_W2A (_string_w, (SQLCHAR*)szInOutConnStr, cbInOutConnStr - 1, &len);
  535. }
  536. done:
  537. MEM_FREE (_string_w);
  538. return retcode;
  539. }
  540. SQLRETURN SQL_API
  541. _iodbcdm_drvchoose_dialboxw (HWND hwnd,
  542. LPWSTR szInOutConnStr,
  543. DWORD cbInOutConnStr,
  544. int FAR * sqlStat)
  545. {
  546. RETCODE retcode = SQL_ERROR;
  547. TDRIVERCHOOSER choose_t;
  548. /* Check input parameters */
  549. if (!hwnd || !szInOutConnStr || cbInOutConnStr < 1)
  550. goto quit;
  551. create_driverchooser (hwnd, &choose_t);
  552. /* Check output parameters */
  553. if (choose_t.driver)
  554. {
  555. if (cbInOutConnStr > WCSLEN (choose_t.driver) + WCSLEN (L"DRIVER="))
  556. {
  557. WCSCPY (szInOutConnStr, L"DRIVER=");
  558. WCSCAT (szInOutConnStr, choose_t.driver);
  559. retcode = SQL_SUCCESS;
  560. }
  561. else
  562. {
  563. if (sqlStat)
  564. #if (ODBCVER>=0x3000)
  565. *sqlStat = en_HY092;
  566. #else
  567. *sqlStat = en_S1000;
  568. #endif
  569. retcode = SQL_ERROR;
  570. }
  571. }
  572. else
  573. retcode = SQL_NO_DATA;
  574. if (choose_t.driver)
  575. free (choose_t.driver);
  576. quit:
  577. return retcode;
  578. }
  579. SQLRETURN SQL_API
  580. _iodbcdm_admin_dialbox (HWND hwnd)
  581. {
  582. RETCODE retcode = SQL_ERROR;
  583. /* Check input parameters */
  584. if (!hwnd)
  585. goto quit;
  586. create_administrator (hwnd);
  587. retcode = SQL_SUCCESS;
  588. quit:
  589. return retcode;
  590. }
  591. SQLRETURN SQL_API
  592. _iodbcdm_trschoose_dialbox (
  593. HWND hwnd,
  594. LPSTR szInOutConnStr,
  595. DWORD cbInOutConnStr,
  596. int FAR * sqlStat)
  597. {
  598. RETCODE retcode = SQL_ERROR;
  599. wchar_t *_string_w = NULL;
  600. WORD len;
  601. if (cbInOutConnStr > 0)
  602. {
  603. if ((_string_w = malloc ((cbInOutConnStr + 1) * sizeof(wchar_t))) == NULL)
  604. goto done;
  605. }
  606. retcode = _iodbcdm_trschoose_dialboxw (hwnd, _string_w,
  607. cbInOutConnStr * sizeof(wchar_t), sqlStat);
  608. if (retcode == SQL_SUCCESS)
  609. {
  610. dm_StrCopyOut2_W2A (_string_w, (SQLCHAR*)szInOutConnStr, cbInOutConnStr - 1, &len);
  611. }
  612. done:
  613. MEM_FREE (_string_w);
  614. return retcode;
  615. }
  616. SQLRETURN SQL_API
  617. _iodbcdm_trschoose_dialboxw (
  618. HWND hwnd,
  619. LPWSTR szInOutConnStr,
  620. DWORD cbInOutConnStr,
  621. int * sqlStat)
  622. {
  623. RETCODE retcode = SQL_ERROR;
  624. TTRANSLATORCHOOSER choose_t;
  625. /* Check input parameters */
  626. if (!hwnd || !szInOutConnStr || cbInOutConnStr < 1)
  627. goto quit;
  628. create_translatorchooser (hwnd, &choose_t);
  629. /* Check output parameters */
  630. if (choose_t.translator)
  631. {
  632. if (cbInOutConnStr >
  633. WCSLEN (choose_t.translator) + WCSLEN (L"TranslationName="))
  634. {
  635. WCSCPY (szInOutConnStr, L"TranslationName");
  636. WCSCAT (szInOutConnStr, choose_t.translator);
  637. retcode = SQL_SUCCESS;
  638. }
  639. else
  640. {
  641. if (sqlStat)
  642. #if (ODBCVER>=0x3000)
  643. *sqlStat = en_HY092;
  644. #else
  645. *sqlStat = en_S1000;
  646. #endif
  647. retcode = SQL_ERROR;
  648. }
  649. }
  650. else
  651. retcode = SQL_NO_DATA;
  652. if (choose_t.translator)
  653. free (choose_t.translator);
  654. quit:
  655. return retcode;
  656. }