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
23 #define WIN32_NO_STATUS
29 #define NONAMELESSUNION
35 #include <wine/debug.h>
39 WINE_DEFAULT_DEBUG_CHANNEL(odbc
);
41 /* Registry key names */
42 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};
44 /* This config mode is known to be process-wide.
45 * MSDN documentation suggests that the value is hidden somewhere in the registry but I haven't found it yet.
46 * Although both the registry and the ODBC.ini files appear to be maintained together they are not maintained automatically through the registry's IniFileMapping.
48 static UWORD config_mode
= ODBC_BOTH_DSN
;
50 /* MSDN documentation suggests that the error subsystem handles errors 1 to 8
51 * only and experimentation (Windows 2000) shows that the errors are process-
52 * wide so go for the simple solution; static arrays.
54 static int num_errors
;
55 static int error_code
[8];
56 static const WCHAR
*error_msg
[8];
57 static const WCHAR odbc_error_general_err
[] = {'G','e','n','e','r','a','l',' ','e','r','r','o','r',0};
58 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};
59 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};
60 static const WCHAR odbc_error_out_of_mem
[] = {'O','u','t',' ','o','f',' ','m','e','m','o','r','y',0};
61 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};
63 /* Push an error onto the error stack, taking care of ranges etc. */
64 static void push_error(int code
, LPCWSTR msg
)
66 if (num_errors
< sizeof error_code
/sizeof error_code
[0])
68 error_code
[num_errors
] = code
;
69 error_msg
[num_errors
] = msg
;
74 /* Clear the error stack */
75 static void clear_errors(void)
80 BOOL WINAPI
ODBCCPlApplet( LONG i
, LONG j
, LONG
* p1
, LONG
* p2
)
83 FIXME( "( %d %d %p %p) : stub!\n", i
, j
, p1
, p2
);
87 static LPWSTR
SQLInstall_strdup_multi(LPCSTR str
)
96 for (p
= str
; *p
; p
+= lstrlenA(p
) + 1)
99 len
= MultiByteToWideChar(CP_ACP
, 0, str
, p
- str
, NULL
, 0 );
100 ret
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
));
101 MultiByteToWideChar(CP_ACP
, 0, str
, p
- str
, ret
, len
);
107 static LPWSTR
SQLInstall_strdup(LPCSTR str
)
115 len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0 );
116 ret
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
117 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
122 /* Convert the wide string or zero-length-terminated list of wide strings to a
123 * narrow string or zero-length-terminated list of narrow strings.
124 * Do not try to emulate windows undocumented excesses (e.g. adding a third \0
127 * mode Indicates the sort of string.
128 * 1 denotes that the buffers contain strings terminated by a single nul
130 * 2 denotes that the buffers contain zero-length-terminated lists
131 * (frequently erroneously referred to as double-null-terminated)
132 * buffer The narrow-character buffer into which to place the result. This
133 * must be a non-null pointer to the first element of a buffer whose
134 * length is passed in buffer_length.
135 * str The wide-character buffer containing the string or list of strings to
136 * be converted. str_length defines how many wide characters in the
137 * buffer are to be converted, including all desired terminating nul
139 * str_length Effective length of str
140 * buffer_length Length of buffer
141 * returned_length A pointer to a variable that will receive the number of
142 * narrow characters placed into the buffer. This pointer
145 static BOOL
SQLInstall_narrow(int mode
, LPSTR buffer
, LPCWSTR str
, WORD str_length
, WORD buffer_length
, WORD
*returned_length
)
147 LPSTR pbuf
; /* allows us to allocate a temporary buffer only if needed */
148 int len
; /* Length of the converted list */
149 BOOL success
= FALSE
;
150 assert(mode
== 1 || mode
== 2);
151 assert(buffer_length
);
152 len
= WideCharToMultiByte(CP_ACP
, 0, str
, str_length
, 0, 0, NULL
, NULL
);
155 if (len
> buffer_length
)
157 pbuf
= HeapAlloc(GetProcessHeap(), 0, len
);
163 len
= WideCharToMultiByte(CP_ACP
, 0, str
, str_length
, pbuf
, len
, NULL
, NULL
);
168 if (buffer_length
> (mode
- 1))
170 memcpy (buffer
, pbuf
, buffer_length
-mode
);
171 *(buffer
+buffer_length
-mode
) = '\0';
173 *(buffer
+buffer_length
-1) = '\0';
177 *returned_length
= pbuf
== buffer
? len
: buffer_length
;
183 ERR("transferring wide to narrow\n");
187 HeapFree(GetProcessHeap(), 0, pbuf
);
192 ERR("measuring wide to narrow\n");
197 BOOL WINAPI
SQLConfigDataSourceW(HWND hwndParent
, WORD fRequest
,
198 LPCWSTR lpszDriver
, LPCWSTR lpszAttributes
)
203 FIXME("%p %d %s %s\n", hwndParent
, fRequest
, debugstr_w(lpszDriver
),
204 debugstr_w(lpszAttributes
));
206 for (p
= lpszAttributes
; *p
; p
+= lstrlenW(p
) + 1)
207 FIXME("%s\n", debugstr_w(p
));
212 BOOL WINAPI
SQLConfigDataSource(HWND hwndParent
, WORD fRequest
,
213 LPCSTR lpszDriver
, LPCSTR lpszAttributes
)
215 FIXME("%p %d %s %s\n", hwndParent
, fRequest
, debugstr_a(lpszDriver
),
216 debugstr_a(lpszAttributes
));
221 BOOL WINAPI
SQLConfigDriverW(HWND hwndParent
, WORD fRequest
, LPCWSTR lpszDriver
,
222 LPCWSTR lpszArgs
, LPWSTR lpszMsg
, WORD cbMsgMax
, WORD
*pcbMsgOut
)
225 FIXME("(%p %d %s %s %p %d %p)\n", hwndParent
, fRequest
, debugstr_w(lpszDriver
),
226 debugstr_w(lpszArgs
), lpszMsg
, cbMsgMax
, pcbMsgOut
);
230 BOOL WINAPI
SQLConfigDriver(HWND hwndParent
, WORD fRequest
, LPCSTR lpszDriver
,
231 LPCSTR lpszArgs
, LPSTR lpszMsg
, WORD cbMsgMax
, WORD
*pcbMsgOut
)
234 FIXME("(%p %d %s %s %p %d %p)\n", hwndParent
, fRequest
, debugstr_a(lpszDriver
),
235 debugstr_a(lpszArgs
), lpszMsg
, cbMsgMax
, pcbMsgOut
);
239 BOOL WINAPI
SQLCreateDataSourceW(HWND hwnd
, LPCWSTR lpszDS
)
243 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
247 BOOL WINAPI
SQLCreateDataSource(HWND hwnd
, LPCSTR lpszDS
)
251 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
255 BOOL WINAPI
SQLGetAvailableDriversW(LPCWSTR lpszInfFile
, LPWSTR lpszBuf
,
256 WORD cbBufMax
, WORD
*pcbBufOut
)
260 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
264 BOOL WINAPI
SQLGetAvailableDrivers(LPCSTR lpszInfFile
, LPSTR lpszBuf
,
265 WORD cbBufMax
, WORD
*pcbBufOut
)
269 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
273 BOOL WINAPI
SQLGetConfigMode(UWORD
*pwConfigMode
)
277 *pwConfigMode
= config_mode
;
281 /* This is implemented sensibly rather than according to exact conformance to Microsoft's buggy implementations
282 * e.g. The Microsoft one occasionally actually adds a third nul character (possibly beyond the buffer).
283 * 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.
285 BOOL WINAPI
SQLGetInstalledDriversW(LPWSTR lpszBuf
, WORD cbBufMax
,
288 HKEY hDrivers
; /* Registry handle to the Drivers key */
289 LONG reg_ret
; /* Return code from registry functions */
290 BOOL success
= FALSE
; /* The value we will return */
293 if (!lpszBuf
|| cbBufMax
== 0)
295 push_error(ODBC_ERROR_INVALID_BUFF_LEN
, odbc_error_invalid_buff_len
);
297 else if ((reg_ret
= RegOpenKeyExW (HKEY_LOCAL_MACHINE
/* The drivers does not depend on the config mode */,
298 drivers_key
, 0, KEY_READ
/* Maybe overkill */,
299 &hDrivers
)) == ERROR_SUCCESS
)
307 size_name
= cbBufMax
;
308 if ((reg_ret
= RegEnumValueW(hDrivers
, index
, lpszBuf
, &size_name
, NULL
, NULL
, NULL
, NULL
)) == ERROR_SUCCESS
)
311 assert (size_name
< cbBufMax
&& *(lpszBuf
+ size_name
) == 0);
313 cbBufMax
-= size_name
;
318 if (reg_ret
!= ERROR_NO_MORE_ITEMS
)
321 push_error(ODBC_ERROR_GENERAL_ERR
, odbc_error_general_err
);
327 if ((reg_ret
= RegCloseKey (hDrivers
)) != ERROR_SUCCESS
)
328 TRACE ("Error %d closing ODBC Drivers key\n", reg_ret
);
332 /* MSDN states that it returns failure with COMPONENT_NOT_FOUND in this case.
333 * Version 3.525.1117.0 (Windows 2000) does not; it actually returns success.
334 * I doubt if it will actually be an issue.
336 push_error(ODBC_ERROR_COMPONENT_NOT_FOUND
, odbc_error_component_not_found
);
341 BOOL WINAPI
SQLGetInstalledDrivers(LPSTR lpszBuf
, WORD cbBufMax
,
345 int size_wbuf
= cbBufMax
;
348 wbuf
= HeapAlloc(GetProcessHeap(), 0, size_wbuf
*sizeof(WCHAR
));
351 ret
= SQLGetInstalledDriversW(wbuf
, size_wbuf
, &size_used
);
354 if (!(ret
= SQLInstall_narrow(2, lpszBuf
, wbuf
, size_used
, cbBufMax
, pcbBufOut
)))
356 push_error(ODBC_ERROR_GENERAL_ERR
, odbc_error_general_err
);
359 HeapFree(GetProcessHeap(), 0, wbuf
);
360 /* ignore failure; we have achieved the aim */
364 push_error(ODBC_ERROR_OUT_OF_MEM
, odbc_error_out_of_mem
);
370 int WINAPI
SQLGetPrivateProfileStringW(LPCWSTR lpszSection
, LPCWSTR lpszEntry
,
371 LPCWSTR lpszDefault
, LPCWSTR RetBuffer
, int cbRetBuffer
,
372 LPCWSTR lpszFilename
)
376 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
380 int WINAPI
SQLGetPrivateProfileString(LPCSTR lpszSection
, LPCSTR lpszEntry
,
381 LPCSTR lpszDefault
, LPCSTR RetBuffer
, int cbRetBuffer
,
386 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
390 BOOL WINAPI
SQLGetTranslatorW(HWND hwndParent
, LPWSTR lpszName
, WORD cbNameMax
,
391 WORD
*pcbNameOut
, LPWSTR lpszPath
, WORD cbPathMax
,
392 WORD
*pcbPathOut
, DWORD
*pvOption
)
396 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
400 BOOL WINAPI
SQLGetTranslator(HWND hwndParent
, LPSTR lpszName
, WORD cbNameMax
,
401 WORD
*pcbNameOut
, LPSTR lpszPath
, WORD cbPathMax
,
402 WORD
*pcbPathOut
, DWORD
*pvOption
)
406 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
410 BOOL WINAPI
SQLInstallDriverW(LPCWSTR lpszInfFile
, LPCWSTR lpszDriver
,
411 LPWSTR lpszPath
, WORD cbPathMax
, WORD
* pcbPathOut
)
416 TRACE("%s %s %p %d %p\n", debugstr_w(lpszInfFile
),
417 debugstr_w(lpszDriver
), lpszPath
, cbPathMax
, pcbPathOut
);
422 return SQLInstallDriverExW(lpszDriver
, NULL
, lpszPath
, cbPathMax
,
423 pcbPathOut
, ODBC_INSTALL_COMPLETE
, &usage
);
426 BOOL WINAPI
SQLInstallDriver(LPCSTR lpszInfFile
, LPCSTR lpszDriver
,
427 LPSTR lpszPath
, WORD cbPathMax
, WORD
* pcbPathOut
)
432 TRACE("%s %s %p %d %p\n", debugstr_a(lpszInfFile
),
433 debugstr_a(lpszDriver
), lpszPath
, cbPathMax
, pcbPathOut
);
438 return SQLInstallDriverEx(lpszDriver
, NULL
, lpszPath
, cbPathMax
,
439 pcbPathOut
, ODBC_INSTALL_COMPLETE
, &usage
);
442 BOOL WINAPI
SQLInstallDriverExW(LPCWSTR lpszDriver
, LPCWSTR lpszPathIn
,
443 LPWSTR lpszPathOut
, WORD cbPathOutMax
, WORD
*pcbPathOut
,
444 WORD fRequest
, LPDWORD lpdwUsageCount
)
448 WCHAR path
[MAX_PATH
];
451 TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszDriver
),
452 debugstr_w(lpszPathIn
), lpszPathOut
, cbPathOutMax
, pcbPathOut
,
453 fRequest
, lpdwUsageCount
);
455 for (p
= lpszDriver
; *p
; p
+= lstrlenW(p
) + 1)
456 TRACE("%s\n", debugstr_w(p
));
458 len
= GetSystemDirectoryW(path
, MAX_PATH
);
463 len
= GetSystemDirectoryW(path
, MAX_PATH
);
465 if (lpszPathOut
&& cbPathOutMax
> len
)
467 lstrcpyW(lpszPathOut
, path
);
473 BOOL WINAPI
SQLInstallDriverEx(LPCSTR lpszDriver
, LPCSTR lpszPathIn
,
474 LPSTR lpszPathOut
, WORD cbPathOutMax
, WORD
*pcbPathOut
,
475 WORD fRequest
, LPDWORD lpdwUsageCount
)
478 LPWSTR driver
, pathin
;
479 WCHAR pathout
[MAX_PATH
];
484 TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszDriver
),
485 debugstr_a(lpszPathIn
), lpszPathOut
, cbPathOutMax
, pcbPathOut
,
486 fRequest
, lpdwUsageCount
);
488 for (p
= lpszDriver
; *p
; p
+= lstrlenA(p
) + 1)
489 TRACE("%s\n", debugstr_a(p
));
491 driver
= SQLInstall_strdup_multi(lpszDriver
);
492 pathin
= SQLInstall_strdup(lpszPathIn
);
494 ret
= SQLInstallDriverExW(driver
, pathin
, pathout
, MAX_PATH
, &cbOut
,
495 fRequest
, lpdwUsageCount
);
498 int len
= WideCharToMultiByte(CP_ACP
, 0, pathout
, -1, lpszPathOut
,
503 *pcbPathOut
= len
- 1;
505 if (!lpszPathOut
|| cbPathOutMax
< len
)
510 len
= WideCharToMultiByte(CP_ACP
, 0, pathout
, -1, lpszPathOut
,
511 cbPathOutMax
, NULL
, NULL
);
516 HeapFree(GetProcessHeap(), 0, driver
);
517 HeapFree(GetProcessHeap(), 0, pathin
);
521 BOOL WINAPI
SQLInstallDriverManagerW(LPWSTR lpszPath
, WORD cbPathMax
,
525 WCHAR path
[MAX_PATH
];
527 TRACE("(%p %d %p)\n", lpszPath
, cbPathMax
, pcbPathOut
);
529 if (cbPathMax
< MAX_PATH
)
534 len
= GetSystemDirectoryW(path
, MAX_PATH
);
539 if (lpszPath
&& cbPathMax
> len
)
541 lstrcpyW(lpszPath
, path
);
547 BOOL WINAPI
SQLInstallDriverManager(LPSTR lpszPath
, WORD cbPathMax
,
552 WCHAR path
[MAX_PATH
];
554 TRACE("(%p %d %p)\n", lpszPath
, cbPathMax
, pcbPathOut
);
556 if (cbPathMax
< MAX_PATH
)
561 ret
= SQLInstallDriverManagerW(path
, MAX_PATH
, &cbOut
);
564 len
= WideCharToMultiByte(CP_ACP
, 0, path
, -1, lpszPath
, 0,
569 *pcbPathOut
= len
- 1;
571 if (!lpszPath
|| cbPathMax
< len
)
574 len
= WideCharToMultiByte(CP_ACP
, 0, path
, -1, lpszPath
,
575 cbPathMax
, NULL
, NULL
);
581 BOOL WINAPI
SQLInstallODBCW(HWND hwndParent
, LPCWSTR lpszInfFile
,
582 LPCWSTR lpszSrcPath
, LPCWSTR lpszDrivers
)
586 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
590 BOOL WINAPI
SQLInstallODBC(HWND hwndParent
, LPCSTR lpszInfFile
,
591 LPCSTR lpszSrcPath
, LPCSTR lpszDrivers
)
595 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
599 SQLRETURN WINAPI
SQLInstallerErrorW(WORD iError
, DWORD
*pfErrorCode
,
600 LPWSTR lpszErrorMsg
, WORD cbErrorMsgMax
, WORD
*pcbErrorMsg
)
602 TRACE("%d %p %p %d %p\n", iError
, pfErrorCode
, lpszErrorMsg
,
603 cbErrorMsgMax
, pcbErrorMsg
);
609 else if (iError
<= num_errors
)
611 BOOL truncated
= FALSE
;
616 *pfErrorCode
= error_code
[iError
];
617 msg
= error_msg
[iError
];
618 len
= msg
? lstrlenW(msg
) : 0;
622 if (cbErrorMsgMax
< len
)
627 if (lpszErrorMsg
&& len
)
631 memcpy (lpszErrorMsg
, msg
, len
* sizeof(WCHAR
));
641 /* Yes. If you pass a null pointer and a large length it is not an error! */
645 return truncated
? SQL_SUCCESS_WITH_INFO
: SQL_SUCCESS
;
648 /* 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 */
652 if (lpszErrorMsg
&& cbErrorMsgMax
> 0)
653 *lpszErrorMsg
= '\0';
658 SQLRETURN WINAPI
SQLInstallerError(WORD iError
, DWORD
*pfErrorCode
,
659 LPSTR lpszErrorMsg
, WORD cbErrorMsgMax
, WORD
*pcbErrorMsg
)
664 TRACE("%d %p %p %d %p\n", iError
, pfErrorCode
, lpszErrorMsg
,
665 cbErrorMsgMax
, pcbErrorMsg
);
668 if (lpszErrorMsg
&& cbErrorMsgMax
)
670 wbuf
= HeapAlloc(GetProcessHeap(), 0, cbErrorMsgMax
*sizeof(WCHAR
));
674 ret
= SQLInstallerErrorW(iError
, pfErrorCode
, wbuf
, cbErrorMsgMax
, &cbwbuf
);
678 SQLInstall_narrow(1, lpszErrorMsg
, wbuf
, cbwbuf
+1, cbErrorMsgMax
, &cbBuf
);
679 HeapFree(GetProcessHeap(), 0, wbuf
);
681 *pcbErrorMsg
= cbBuf
-1;
686 BOOL WINAPI
SQLInstallTranslatorExW(LPCWSTR lpszTranslator
, LPCWSTR lpszPathIn
,
687 LPWSTR lpszPathOut
, WORD cbPathOutMax
, WORD
*pcbPathOut
,
688 WORD fRequest
, LPDWORD lpdwUsageCount
)
692 WCHAR path
[MAX_PATH
];
695 TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszTranslator
),
696 debugstr_w(lpszPathIn
), lpszPathOut
, cbPathOutMax
, pcbPathOut
,
697 fRequest
, lpdwUsageCount
);
699 for (p
= lpszTranslator
; *p
; p
+= lstrlenW(p
) + 1)
700 TRACE("%s\n", debugstr_w(p
));
702 len
= GetSystemDirectoryW(path
, MAX_PATH
);
707 if (lpszPathOut
&& cbPathOutMax
> len
)
709 lstrcpyW(lpszPathOut
, path
);
715 BOOL WINAPI
SQLInstallTranslatorEx(LPCSTR lpszTranslator
, LPCSTR lpszPathIn
,
716 LPSTR lpszPathOut
, WORD cbPathOutMax
, WORD
*pcbPathOut
,
717 WORD fRequest
, LPDWORD lpdwUsageCount
)
720 LPWSTR translator
, pathin
;
721 WCHAR pathout
[MAX_PATH
];
726 TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszTranslator
),
727 debugstr_a(lpszPathIn
), lpszPathOut
, cbPathOutMax
, pcbPathOut
,
728 fRequest
, lpdwUsageCount
);
730 for (p
= lpszTranslator
; *p
; p
+= lstrlenA(p
) + 1)
731 TRACE("%s\n", debugstr_a(p
));
733 translator
= SQLInstall_strdup_multi(lpszTranslator
);
734 pathin
= SQLInstall_strdup(lpszPathIn
);
736 ret
= SQLInstallTranslatorExW(translator
, pathin
, pathout
, MAX_PATH
,
737 &cbOut
, fRequest
, lpdwUsageCount
);
740 int len
= WideCharToMultiByte(CP_ACP
, 0, pathout
, -1, lpszPathOut
,
745 *pcbPathOut
= len
- 1;
747 if (!lpszPathOut
|| cbPathOutMax
< len
)
752 len
= WideCharToMultiByte(CP_ACP
, 0, pathout
, -1, lpszPathOut
,
753 cbPathOutMax
, NULL
, NULL
);
758 HeapFree(GetProcessHeap(), 0, translator
);
759 HeapFree(GetProcessHeap(), 0, pathin
);
763 BOOL WINAPI
SQLInstallTranslator(LPCSTR lpszInfFile
, LPCSTR lpszTranslator
,
764 LPCSTR lpszPathIn
, LPSTR lpszPathOut
, WORD cbPathOutMax
,
765 WORD
*pcbPathOut
, WORD fRequest
, LPDWORD lpdwUsageCount
)
768 TRACE("%s %s %s %p %d %p %d %p\n", debugstr_a(lpszInfFile
),
769 debugstr_a(lpszTranslator
), debugstr_a(lpszPathIn
), lpszPathOut
,
770 cbPathOutMax
, pcbPathOut
, fRequest
, lpdwUsageCount
);
775 return SQLInstallTranslatorEx(lpszTranslator
, lpszPathIn
, lpszPathOut
,
776 cbPathOutMax
, pcbPathOut
, fRequest
, lpdwUsageCount
);
779 BOOL WINAPI
SQLInstallTranslatorW(LPCWSTR lpszInfFile
, LPCWSTR lpszTranslator
,
780 LPCWSTR lpszPathIn
, LPWSTR lpszPathOut
, WORD cbPathOutMax
,
781 WORD
*pcbPathOut
, WORD fRequest
, LPDWORD lpdwUsageCount
)
784 TRACE("%s %s %s %p %d %p %d %p\n", debugstr_w(lpszInfFile
),
785 debugstr_w(lpszTranslator
), debugstr_w(lpszPathIn
), lpszPathOut
,
786 cbPathOutMax
, pcbPathOut
, fRequest
, lpdwUsageCount
);
791 return SQLInstallTranslatorExW(lpszTranslator
, lpszPathIn
, lpszPathOut
,
792 cbPathOutMax
, pcbPathOut
, fRequest
, lpdwUsageCount
);
795 BOOL WINAPI
SQLManageDataSources(HWND hwnd
)
799 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
803 SQLRETURN WINAPI
SQLPostInstallerErrorW(DWORD fErrorCode
, LPCWSTR szErrorMsg
)
806 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
810 SQLRETURN WINAPI
SQLPostInstallerError(DWORD fErrorCode
, LPCSTR szErrorMsg
)
813 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
817 BOOL WINAPI
SQLReadFileDSNW(LPCWSTR lpszFileName
, LPCWSTR lpszAppName
,
818 LPCWSTR lpszKeyName
, LPWSTR lpszString
, WORD cbString
,
823 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
827 BOOL WINAPI
SQLReadFileDSN(LPCSTR lpszFileName
, LPCSTR lpszAppName
,
828 LPCSTR lpszKeyName
, LPSTR lpszString
, WORD cbString
,
833 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
837 BOOL WINAPI
SQLRemoveDefaultDataSource(void)
841 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
845 BOOL WINAPI
SQLRemoveDriverW(LPCWSTR lpszDriver
, BOOL fRemoveDSN
,
846 LPDWORD lpdwUsageCount
)
850 if (lpdwUsageCount
) *lpdwUsageCount
= 1;
854 BOOL WINAPI
SQLRemoveDriver(LPCSTR lpszDriver
, BOOL fRemoveDSN
,
855 LPDWORD lpdwUsageCount
)
859 if (lpdwUsageCount
) *lpdwUsageCount
= 1;
863 BOOL WINAPI
SQLRemoveDriverManager(LPDWORD pdwUsageCount
)
867 if (pdwUsageCount
) *pdwUsageCount
= 1;
871 BOOL WINAPI
SQLRemoveDSNFromIniW(LPCWSTR lpszDSN
)
875 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
879 BOOL WINAPI
SQLRemoveDSNFromIni(LPCSTR lpszDSN
)
883 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
887 BOOL WINAPI
SQLRemoveTranslatorW(LPCWSTR lpszTranslator
, LPDWORD lpdwUsageCount
)
891 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
895 BOOL WINAPI
SQLRemoveTranslator(LPCSTR lpszTranslator
, LPDWORD lpdwUsageCount
)
899 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
903 BOOL WINAPI
SQLSetConfigMode(UWORD wConfigMode
)
906 if (wConfigMode
> ODBC_SYSTEM_DSN
)
908 push_error(ODBC_ERROR_INVALID_PARAM_SEQUENCE
, odbc_error_invalid_param_sequence
);
913 config_mode
= wConfigMode
;
918 BOOL WINAPI
SQLValidDSNW(LPCWSTR lpszDSN
)
922 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
926 BOOL WINAPI
SQLValidDSN(LPCSTR lpszDSN
)
930 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
934 BOOL WINAPI
SQLWriteDSNToIniW(LPCWSTR lpszDSN
, LPCWSTR lpszDriver
)
938 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
942 BOOL WINAPI
SQLWriteDSNToIni(LPCSTR lpszDSN
, LPCSTR lpszDriver
)
946 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
950 BOOL WINAPI
SQLWriteFileDSNW(LPCWSTR lpszFileName
, LPCWSTR lpszAppName
,
951 LPCWSTR lpszKeyName
, LPCWSTR lpszString
)
955 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
959 BOOL WINAPI
SQLWriteFileDSN(LPCSTR lpszFileName
, LPCSTR lpszAppName
,
960 LPCSTR lpszKeyName
, LPCSTR lpszString
)
964 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
968 BOOL WINAPI
SQLWritePrivateProfileStringW(LPCWSTR lpszSection
, LPCWSTR lpszEntry
,
969 LPCWSTR lpszString
, LPCWSTR lpszFilename
)
973 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
977 BOOL WINAPI
SQLWritePrivateProfileString(LPCSTR lpszSection
, LPCSTR lpszEntry
,
978 LPCSTR lpszString
, LPCSTR lpszFilename
)
982 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);