2 * Implementation of the ODBC driver installer
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 * Copyright 2005 Hans Leidekker
6 * Copyright 2007 Bill Medland
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #define NONAMELESSUNION
33 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(odbc);
39 /* Registry key names */
40 static const WCHAR drivers_key[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','O','D','B','C','I','N','S','T','.','I','N','I','\\','O','D','B','C',' ','D','r','i','v','e','r','s',0};
42 /* This config mode is known to be process-wide.
43 * MSDN documentation suggests that the value is hidden somewhere in the registry but I haven't found it yet.
44 * Although both the registry and the ODBC.ini files appear to be maintained together they are not maintained automatically through the registry's IniFileMapping.
46 static UWORD config_mode = ODBC_BOTH_DSN;
48 /* MSDN documentation suggests that the error subsystem handles errors 1 to 8
49 * only and experimentation (Windows 2000) shows that the errors are process-
50 * wide so go for the simple solution; static arrays.
52 static int num_errors;
53 static int error_code[8];
54 static const WCHAR *error_msg[8];
55 static const WCHAR odbc_error_general_err[] = {'G','e','n','e','r','a','l',' ','e','r','r','o','r',0};
56 static const WCHAR odbc_error_invalid_buff_len[] = {'I','n','v','a','l','i','d',' ','b','u','f','f','e','r',' ','l','e','n','g','t','h',0};
57 static const WCHAR odbc_error_component_not_found[] = {'C','o','m','p','o','n','e','n','t',' ','n','o','t',' ','f','o','u','n','d',0};
58 static const WCHAR odbc_error_out_of_mem[] = {'O','u','t',' ','o','f',' ','m','e','m','o','r','y',0};
59 static const WCHAR odbc_error_invalid_param_sequence[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','e','q','u','e','n','c','e',0};
61 /* Push an error onto the error stack, taking care of ranges etc. */
62 static void push_error(int code, LPCWSTR msg)
64 if (num_errors < sizeof error_code/sizeof error_code[0])
66 error_code[num_errors] = code;
67 error_msg[num_errors] = msg;
72 /* Clear the error stack */
73 static void clear_errors(void)
78 BOOL WINAPI ODBCCPlApplet( LONG i, LONG j, LONG * p1, LONG * p2)
81 FIXME( "( %d %d %p %p) : stub!\n", i, j, p1, p2);
85 static LPWSTR SQLInstall_strdup_multi(LPCSTR str)
94 for (p = str; *p; p += lstrlenA(p) + 1)
97 len = MultiByteToWideChar(CP_ACP, 0, str, p - str, NULL, 0 );
98 ret = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
99 MultiByteToWideChar(CP_ACP, 0, str, p - str, ret, len );
105 static LPWSTR SQLInstall_strdup(LPCSTR str)
113 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0 );
114 ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
115 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len );
120 /* Convert the wide string or zero-length-terminated list of wide strings to a
121 * narrow string or zero-length-terminated list of narrow strings.
122 * Do not try to emulate windows undocumented excesses (e.g. adding a third \0
125 * mode Indicates the sort of string.
126 * 1 denotes that the buffers contain strings terminated by a single nul
128 * 2 denotes that the buffers contain zero-length-terminated lists
129 * (frequently erroneously referred to as double-null-terminated)
130 * buffer The narrow-character buffer into which to place the result. This
131 * must be a non-null pointer to the first element of a buffer whose
132 * length is passed in buffer_length.
133 * str The wide-character buffer containing the string or list of strings to
134 * be converted. str_length defines how many wide characters in the
135 * buffer are to be converted, including all desired terminating nul
137 * str_length Effective length of str
138 * buffer_length Length of buffer
139 * returned_length A pointer to a variable that will receive the number of
140 * narrow characters placed into the buffer. This pointer
143 static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_length, WORD buffer_length, WORD *returned_length)
145 LPSTR pbuf; /* allows us to allocate a temporary buffer only if needed */
146 int len; /* Length of the converted list */
147 BOOL success = FALSE;
148 assert(mode == 1 || mode == 2);
149 assert(buffer_length);
150 len = WideCharToMultiByte(CP_ACP, 0, str, str_length, 0, 0, NULL, NULL);
153 if (len > buffer_length)
155 pbuf = HeapAlloc(GetProcessHeap(), 0, len);
161 len = WideCharToMultiByte(CP_ACP, 0, str, str_length, pbuf, len, NULL, NULL);
166 if (buffer_length > (mode - 1))
168 memcpy (buffer, pbuf, buffer_length-mode);
169 *(buffer+buffer_length-mode) = '\0';
171 *(buffer+buffer_length-1) = '\0';
175 *returned_length = pbuf == buffer ? len : buffer_length;
181 ERR("transferring wide to narrow\n");
185 HeapFree(GetProcessHeap(), 0, pbuf);
190 ERR("measuring wide to narrow\n");
195 BOOL WINAPI SQLConfigDataSourceW(HWND hwndParent, WORD fRequest,
196 LPCWSTR lpszDriver, LPCWSTR lpszAttributes)
201 FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_w(lpszDriver),
202 debugstr_w(lpszAttributes));
204 for (p = lpszAttributes; *p; p += lstrlenW(p) + 1)
205 FIXME("%s\n", debugstr_w(p));
210 BOOL WINAPI SQLConfigDataSource(HWND hwndParent, WORD fRequest,
211 LPCSTR lpszDriver, LPCSTR lpszAttributes)
213 FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_a(lpszDriver),
214 debugstr_a(lpszAttributes));
219 BOOL WINAPI SQLConfigDriverW(HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver,
220 LPCWSTR lpszArgs, LPWSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut)
223 FIXME("(%p %d %s %s %p %d %p)\n", hwndParent, fRequest, debugstr_w(lpszDriver),
224 debugstr_w(lpszArgs), lpszMsg, cbMsgMax, pcbMsgOut);
228 BOOL WINAPI SQLConfigDriver(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver,
229 LPCSTR lpszArgs, LPSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut)
232 FIXME("(%p %d %s %s %p %d %p)\n", hwndParent, fRequest, debugstr_a(lpszDriver),
233 debugstr_a(lpszArgs), lpszMsg, cbMsgMax, pcbMsgOut);
237 BOOL WINAPI SQLCreateDataSourceW(HWND hwnd, LPCWSTR lpszDS)
241 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
245 BOOL WINAPI SQLCreateDataSource(HWND hwnd, LPCSTR lpszDS)
249 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
253 BOOL WINAPI SQLGetAvailableDriversW(LPCWSTR lpszInfFile, LPWSTR lpszBuf,
254 WORD cbBufMax, WORD *pcbBufOut)
258 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
262 BOOL WINAPI SQLGetAvailableDrivers(LPCSTR lpszInfFile, LPSTR lpszBuf,
263 WORD cbBufMax, WORD *pcbBufOut)
267 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
271 BOOL WINAPI SQLGetConfigMode(UWORD *pwConfigMode)
275 *pwConfigMode = config_mode;
279 /* This is implemented sensibly rather than according to exact conformance to Microsoft's buggy implementations
280 * e.g. The Microsoft one occasionally actually adds a third nul character (possibly beyond the buffer).
281 * e.g. If the key has no drivers then version 3.525.1117.0 does not modify the buffer at all, not even a nul character.
283 BOOL WINAPI SQLGetInstalledDriversW(LPWSTR lpszBuf, WORD cbBufMax,
286 HKEY hDrivers; /* Registry handle to the Drivers key */
287 LONG reg_ret; /* Return code from registry functions */
288 BOOL success = FALSE; /* The value we will return */
291 if (!lpszBuf || cbBufMax == 0)
293 push_error(ODBC_ERROR_INVALID_BUFF_LEN, odbc_error_invalid_buff_len);
295 else if ((reg_ret = RegOpenKeyExW (HKEY_LOCAL_MACHINE /* The drivers does not depend on the config mode */,
296 drivers_key, 0, KEY_READ /* Maybe overkill */,
297 &hDrivers)) == ERROR_SUCCESS)
305 size_name = cbBufMax;
306 if ((reg_ret = RegEnumValueW(hDrivers, index, lpszBuf, &size_name, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)
309 assert (size_name < cbBufMax && *(lpszBuf + size_name) == 0);
311 cbBufMax-= size_name;
316 if (reg_ret != ERROR_NO_MORE_ITEMS)
319 push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err);
325 if ((reg_ret = RegCloseKey (hDrivers)) != ERROR_SUCCESS)
326 TRACE ("Error %d closing ODBC Drivers key\n", reg_ret);
330 /* MSDN states that it returns failure with COMPONENT_NOT_FOUND in this case.
331 * Version 3.525.1117.0 (Windows 2000) does not; it actually returns success.
332 * I doubt if it will actually be an issue.
334 push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found);
339 BOOL WINAPI SQLGetInstalledDrivers(LPSTR lpszBuf, WORD cbBufMax,
343 int size_wbuf = cbBufMax;
346 wbuf = HeapAlloc(GetProcessHeap(), 0, size_wbuf*sizeof(WCHAR));
349 ret = SQLGetInstalledDriversW(wbuf, size_wbuf, &size_used);
352 if (!(ret = SQLInstall_narrow(2, lpszBuf, wbuf, size_used, cbBufMax, pcbBufOut)))
354 push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err);
357 HeapFree(GetProcessHeap(), 0, wbuf);
358 /* ignore failure; we have achieved the aim */
362 push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
368 int WINAPI SQLGetPrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry,
369 LPCWSTR lpszDefault, LPCWSTR RetBuffer, int cbRetBuffer,
370 LPCWSTR lpszFilename)
374 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
378 int WINAPI SQLGetPrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry,
379 LPCSTR lpszDefault, LPCSTR RetBuffer, int cbRetBuffer,
384 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
388 BOOL WINAPI SQLGetTranslatorW(HWND hwndParent, LPWSTR lpszName, WORD cbNameMax,
389 WORD *pcbNameOut, LPWSTR lpszPath, WORD cbPathMax,
390 WORD *pcbPathOut, DWORD *pvOption)
394 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
398 BOOL WINAPI SQLGetTranslator(HWND hwndParent, LPSTR lpszName, WORD cbNameMax,
399 WORD *pcbNameOut, LPSTR lpszPath, WORD cbPathMax,
400 WORD *pcbPathOut, DWORD *pvOption)
404 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
408 BOOL WINAPI SQLInstallDriverW(LPCWSTR lpszInfFile, LPCWSTR lpszDriver,
409 LPWSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut)
414 TRACE("%s %s %p %d %p\n", debugstr_w(lpszInfFile),
415 debugstr_w(lpszDriver), lpszPath, cbPathMax, pcbPathOut);
420 return SQLInstallDriverExW(lpszDriver, NULL, lpszPath, cbPathMax,
421 pcbPathOut, ODBC_INSTALL_COMPLETE, &usage);
424 BOOL WINAPI SQLInstallDriver(LPCSTR lpszInfFile, LPCSTR lpszDriver,
425 LPSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut)
430 TRACE("%s %s %p %d %p\n", debugstr_a(lpszInfFile),
431 debugstr_a(lpszDriver), lpszPath, cbPathMax, pcbPathOut);
436 return SQLInstallDriverEx(lpszDriver, NULL, lpszPath, cbPathMax,
437 pcbPathOut, ODBC_INSTALL_COMPLETE, &usage);
440 BOOL WINAPI SQLInstallDriverExW(LPCWSTR lpszDriver, LPCWSTR lpszPathIn,
441 LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
442 WORD fRequest, LPDWORD lpdwUsageCount)
446 WCHAR path[MAX_PATH];
449 TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszDriver),
450 debugstr_w(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
451 fRequest, lpdwUsageCount);
453 for (p = lpszDriver; *p; p += lstrlenW(p) + 1)
454 TRACE("%s\n", debugstr_w(p));
456 len = GetSystemDirectoryW(path, MAX_PATH);
461 len = GetSystemDirectoryW(path, MAX_PATH);
463 if (lpszPathOut && cbPathOutMax > len)
465 lstrcpyW(lpszPathOut, path);
471 BOOL WINAPI SQLInstallDriverEx(LPCSTR lpszDriver, LPCSTR lpszPathIn,
472 LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
473 WORD fRequest, LPDWORD lpdwUsageCount)
476 LPWSTR driver, pathin;
477 WCHAR pathout[MAX_PATH];
482 TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszDriver),
483 debugstr_a(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
484 fRequest, lpdwUsageCount);
486 for (p = lpszDriver; *p; p += lstrlenA(p) + 1)
487 TRACE("%s\n", debugstr_a(p));
489 driver = SQLInstall_strdup_multi(lpszDriver);
490 pathin = SQLInstall_strdup(lpszPathIn);
492 ret = SQLInstallDriverExW(driver, pathin, pathout, MAX_PATH, &cbOut,
493 fRequest, lpdwUsageCount);
496 int len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
501 *pcbPathOut = len - 1;
503 if (!lpszPathOut || cbPathOutMax < len)
508 len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
509 cbPathOutMax, NULL, NULL);
514 HeapFree(GetProcessHeap(), 0, driver);
515 HeapFree(GetProcessHeap(), 0, pathin);
519 BOOL WINAPI SQLInstallDriverManagerW(LPWSTR lpszPath, WORD cbPathMax,
523 WCHAR path[MAX_PATH];
525 TRACE("(%p %d %p)\n", lpszPath, cbPathMax, pcbPathOut);
527 if (cbPathMax < MAX_PATH)
532 len = GetSystemDirectoryW(path, MAX_PATH);
537 if (lpszPath && cbPathMax > len)
539 lstrcpyW(lpszPath, path);
545 BOOL WINAPI SQLInstallDriverManager(LPSTR lpszPath, WORD cbPathMax,
550 WCHAR path[MAX_PATH];
552 TRACE("(%p %d %p)\n", lpszPath, cbPathMax, pcbPathOut);
554 if (cbPathMax < MAX_PATH)
559 ret = SQLInstallDriverManagerW(path, MAX_PATH, &cbOut);
562 len = WideCharToMultiByte(CP_ACP, 0, path, -1, lpszPath, 0,
567 *pcbPathOut = len - 1;
569 if (!lpszPath || cbPathMax < len)
572 len = WideCharToMultiByte(CP_ACP, 0, path, -1, lpszPath,
573 cbPathMax, NULL, NULL);
579 BOOL WINAPI SQLInstallODBCW(HWND hwndParent, LPCWSTR lpszInfFile,
580 LPCWSTR lpszSrcPath, LPCWSTR lpszDrivers)
584 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
588 BOOL WINAPI SQLInstallODBC(HWND hwndParent, LPCSTR lpszInfFile,
589 LPCSTR lpszSrcPath, LPCSTR lpszDrivers)
593 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
597 SQLRETURN WINAPI SQLInstallerErrorW(WORD iError, DWORD *pfErrorCode,
598 LPWSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
600 TRACE("%d %p %p %d %p\n", iError, pfErrorCode, lpszErrorMsg,
601 cbErrorMsgMax, pcbErrorMsg);
607 else if (iError <= num_errors)
609 BOOL truncated = FALSE;
614 *pfErrorCode = error_code[iError];
615 msg = error_msg[iError];
616 len = msg ? lstrlenW(msg) : 0;
620 if (cbErrorMsgMax < len)
625 if (lpszErrorMsg && len)
629 memcpy (lpszErrorMsg, msg, len * sizeof(WCHAR));
639 /* Yes. If you pass a null pointer and a large length it is not an error! */
643 return truncated ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
646 /* At least on Windows 2000 , the buffers are not altered in this case. However that is a little too dangerous a test for just now */
650 if (lpszErrorMsg && cbErrorMsgMax > 0)
651 *lpszErrorMsg = '\0';
656 SQLRETURN WINAPI SQLInstallerError(WORD iError, DWORD *pfErrorCode,
657 LPSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
662 TRACE("%d %p %p %d %p\n", iError, pfErrorCode, lpszErrorMsg,
663 cbErrorMsgMax, pcbErrorMsg);
666 if (lpszErrorMsg && cbErrorMsgMax)
668 wbuf = HeapAlloc(GetProcessHeap(), 0, cbErrorMsgMax*sizeof(WCHAR));
672 ret = SQLInstallerErrorW(iError, pfErrorCode, wbuf, cbErrorMsgMax, &cbwbuf);
676 SQLInstall_narrow(1, lpszErrorMsg, wbuf, cbwbuf+1, cbErrorMsgMax, &cbBuf);
677 HeapFree(GetProcessHeap(), 0, wbuf);
679 *pcbErrorMsg = cbBuf-1;
684 BOOL WINAPI SQLInstallTranslatorExW(LPCWSTR lpszTranslator, LPCWSTR lpszPathIn,
685 LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
686 WORD fRequest, LPDWORD lpdwUsageCount)
690 WCHAR path[MAX_PATH];
693 TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszTranslator),
694 debugstr_w(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
695 fRequest, lpdwUsageCount);
697 for (p = lpszTranslator; *p; p += lstrlenW(p) + 1)
698 TRACE("%s\n", debugstr_w(p));
700 len = GetSystemDirectoryW(path, MAX_PATH);
705 if (lpszPathOut && cbPathOutMax > len)
707 lstrcpyW(lpszPathOut, path);
713 BOOL WINAPI SQLInstallTranslatorEx(LPCSTR lpszTranslator, LPCSTR lpszPathIn,
714 LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
715 WORD fRequest, LPDWORD lpdwUsageCount)
718 LPWSTR translator, pathin;
719 WCHAR pathout[MAX_PATH];
724 TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszTranslator),
725 debugstr_a(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
726 fRequest, lpdwUsageCount);
728 for (p = lpszTranslator; *p; p += lstrlenA(p) + 1)
729 TRACE("%s\n", debugstr_a(p));
731 translator = SQLInstall_strdup_multi(lpszTranslator);
732 pathin = SQLInstall_strdup(lpszPathIn);
734 ret = SQLInstallTranslatorExW(translator, pathin, pathout, MAX_PATH,
735 &cbOut, fRequest, lpdwUsageCount);
738 int len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
743 *pcbPathOut = len - 1;
745 if (!lpszPathOut || cbPathOutMax < len)
750 len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
751 cbPathOutMax, NULL, NULL);
756 HeapFree(GetProcessHeap(), 0, translator);
757 HeapFree(GetProcessHeap(), 0, pathin);
761 BOOL WINAPI SQLInstallTranslator(LPCSTR lpszInfFile, LPCSTR lpszTranslator,
762 LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax,
763 WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
766 TRACE("%s %s %s %p %d %p %d %p\n", debugstr_a(lpszInfFile),
767 debugstr_a(lpszTranslator), debugstr_a(lpszPathIn), lpszPathOut,
768 cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
773 return SQLInstallTranslatorEx(lpszTranslator, lpszPathIn, lpszPathOut,
774 cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
777 BOOL WINAPI SQLInstallTranslatorW(LPCWSTR lpszInfFile, LPCWSTR lpszTranslator,
778 LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax,
779 WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
782 TRACE("%s %s %s %p %d %p %d %p\n", debugstr_w(lpszInfFile),
783 debugstr_w(lpszTranslator), debugstr_w(lpszPathIn), lpszPathOut,
784 cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
789 return SQLInstallTranslatorExW(lpszTranslator, lpszPathIn, lpszPathOut,
790 cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
793 BOOL WINAPI SQLManageDataSources(HWND hwnd)
797 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
801 SQLRETURN WINAPI SQLPostInstallerErrorW(DWORD fErrorCode, LPCWSTR szErrorMsg)
804 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
808 SQLRETURN WINAPI SQLPostInstallerError(DWORD fErrorCode, LPCSTR szErrorMsg)
811 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
815 BOOL WINAPI SQLReadFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
816 LPCWSTR lpszKeyName, LPWSTR lpszString, WORD cbString,
821 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
825 BOOL WINAPI SQLReadFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName,
826 LPCSTR lpszKeyName, LPSTR lpszString, WORD cbString,
831 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
835 BOOL WINAPI SQLRemoveDefaultDataSource(void)
839 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
843 BOOL WINAPI SQLRemoveDriverW(LPCWSTR lpszDriver, BOOL fRemoveDSN,
844 LPDWORD lpdwUsageCount)
851 BOOL WINAPI SQLRemoveDriver(LPCSTR lpszDriver, BOOL fRemoveDSN,
852 LPDWORD lpdwUsageCount)
859 BOOL WINAPI SQLRemoveDriverManager(LPDWORD pdwUsageCount)
866 BOOL WINAPI SQLRemoveDSNFromIniW(LPCWSTR lpszDSN)
870 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
874 BOOL WINAPI SQLRemoveDSNFromIni(LPCSTR lpszDSN)
878 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
882 BOOL WINAPI SQLRemoveTranslatorW(LPCWSTR lpszTranslator, LPDWORD lpdwUsageCount)
886 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
890 BOOL WINAPI SQLRemoveTranslator(LPCSTR lpszTranslator, LPDWORD lpdwUsageCount)
894 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
898 BOOL WINAPI SQLSetConfigMode(UWORD wConfigMode)
901 if (wConfigMode > ODBC_SYSTEM_DSN)
903 push_error(ODBC_ERROR_INVALID_PARAM_SEQUENCE, odbc_error_invalid_param_sequence);
908 config_mode = wConfigMode;
913 BOOL WINAPI SQLValidDSNW(LPCWSTR lpszDSN)
917 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
921 BOOL WINAPI SQLValidDSN(LPCSTR lpszDSN)
925 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
929 BOOL WINAPI SQLWriteDSNToIniW(LPCWSTR lpszDSN, LPCWSTR lpszDriver)
933 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
937 BOOL WINAPI SQLWriteDSNToIni(LPCSTR lpszDSN, LPCSTR lpszDriver)
941 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
945 BOOL WINAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
946 LPCWSTR lpszKeyName, LPCWSTR lpszString)
950 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
954 BOOL WINAPI SQLWriteFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName,
955 LPCSTR lpszKeyName, LPCSTR lpszString)
959 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
963 BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry,
964 LPCWSTR lpszString, LPCWSTR lpszFilename)
968 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
972 BOOL WINAPI SQLWritePrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry,
973 LPCSTR lpszString, LPCSTR lpszFilename)
977 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);