odbccp32: Clean up SQLGetInstalledDrivers().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
99562a5617
commit
169960b676
|
@ -482,99 +482,97 @@ BOOL WINAPI SQLGetConfigMode(UWORD *pwConfigMode)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is implemented sensibly rather than according to exact conformance to Microsoft's buggy implementations
|
BOOL WINAPI SQLGetInstalledDriversW(WCHAR *buf, WORD size, WORD *sizeout)
|
||||||
* e.g. The Microsoft one occasionally actually adds a third nul character (possibly beyond the buffer).
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
BOOL WINAPI SQLGetInstalledDriversW(LPWSTR lpszBuf, WORD cbBufMax,
|
|
||||||
WORD *pcbBufOut)
|
|
||||||
{
|
{
|
||||||
HKEY hDrivers; /* Registry handle to the Drivers key */
|
WORD written = 0;
|
||||||
LONG reg_ret; /* Return code from registry functions */
|
DWORD index = 0;
|
||||||
BOOL success = FALSE; /* The value we will return */
|
BOOL ret = TRUE;
|
||||||
|
DWORD valuelen;
|
||||||
|
WCHAR *value;
|
||||||
|
HKEY drivers;
|
||||||
|
DWORD len;
|
||||||
|
LONG res;
|
||||||
|
|
||||||
clear_errors();
|
clear_errors();
|
||||||
|
|
||||||
TRACE("%p %d %p\n", lpszBuf, cbBufMax, pcbBufOut);
|
TRACE("%p %d %p\n", buf, size, sizeout);
|
||||||
|
|
||||||
if (!lpszBuf || cbBufMax == 0)
|
if (!buf || !size)
|
||||||
{
|
{
|
||||||
push_error(ODBC_ERROR_INVALID_BUFF_LEN, odbc_error_invalid_buff_len);
|
push_error(ODBC_ERROR_INVALID_BUFF_LEN, odbc_error_invalid_buff_len);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if ((reg_ret = RegOpenKeyExW (HKEY_LOCAL_MACHINE /* The drivers does not depend on the config mode */,
|
|
||||||
drivers_key, 0, KEY_READ /* Maybe overkill */,
|
res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drivers_key, 0, KEY_QUERY_VALUE, &drivers);
|
||||||
&hDrivers)) == ERROR_SUCCESS)
|
if (res)
|
||||||
{
|
{
|
||||||
DWORD index = 0;
|
|
||||||
cbBufMax--;
|
|
||||||
success = TRUE;
|
|
||||||
while (cbBufMax > 0)
|
|
||||||
{
|
|
||||||
DWORD size_name;
|
|
||||||
size_name = cbBufMax;
|
|
||||||
if ((reg_ret = RegEnumValueW(hDrivers, index, lpszBuf, &size_name, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
index++;
|
|
||||||
assert (size_name < cbBufMax && *(lpszBuf + size_name) == 0);
|
|
||||||
size_name++;
|
|
||||||
cbBufMax-= size_name;
|
|
||||||
lpszBuf+=size_name;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (reg_ret != ERROR_NO_MORE_ITEMS)
|
|
||||||
{
|
|
||||||
success = FALSE;
|
|
||||||
push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*lpszBuf = 0;
|
|
||||||
if ((reg_ret = RegCloseKey (hDrivers)) != ERROR_SUCCESS)
|
|
||||||
TRACE ("Error %d closing ODBC Drivers key\n", reg_ret);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* MSDN states that it returns failure with COMPONENT_NOT_FOUND in this case.
|
|
||||||
* Version 3.525.1117.0 (Windows 2000) does not; it actually returns success.
|
|
||||||
* I doubt if it will actually be an issue.
|
|
||||||
*/
|
|
||||||
push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found);
|
push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
return success;
|
|
||||||
|
RegQueryInfoKeyW(drivers, 0, 0, 0, 0, 0, 0, 0, &valuelen, 0, 0, 0);
|
||||||
|
value = heap_alloc(++valuelen * sizeof(WCHAR));
|
||||||
|
|
||||||
|
size--;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
len = valuelen;
|
||||||
|
res = RegEnumValueW(drivers, index++, value, &len, NULL, NULL, NULL, NULL);
|
||||||
|
if (res == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
lstrcpynW(buf + written, value, size - written);
|
||||||
|
written += min(len + 1, size - written);
|
||||||
|
}
|
||||||
|
else if (res == ERROR_NO_MORE_ITEMS)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err);
|
||||||
|
ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[written++] = 0;
|
||||||
|
|
||||||
|
heap_free(value);
|
||||||
|
RegCloseKey(drivers);
|
||||||
|
if (sizeout)
|
||||||
|
*sizeout = written;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI SQLGetInstalledDrivers(LPSTR lpszBuf, WORD cbBufMax,
|
BOOL WINAPI SQLGetInstalledDrivers(char *buf, WORD size, WORD *sizeout)
|
||||||
WORD *pcbBufOut)
|
|
||||||
{
|
{
|
||||||
|
WORD written;
|
||||||
|
WCHAR *wbuf;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
int size_wbuf = cbBufMax;
|
|
||||||
LPWSTR wbuf;
|
|
||||||
WORD size_used;
|
|
||||||
|
|
||||||
TRACE("%p %d %p\n", lpszBuf, cbBufMax, pcbBufOut);
|
TRACE("%p %d %p\n", buf, size, sizeout);
|
||||||
|
|
||||||
wbuf = HeapAlloc(GetProcessHeap(), 0, size_wbuf*sizeof(WCHAR));
|
if (!buf || !size)
|
||||||
if (wbuf)
|
|
||||||
{
|
{
|
||||||
ret = SQLGetInstalledDriversW(wbuf, size_wbuf, &size_used);
|
push_error(ODBC_ERROR_INVALID_BUFF_LEN, odbc_error_invalid_buff_len);
|
||||||
if (ret)
|
return FALSE;
|
||||||
{
|
|
||||||
if (!(ret = SQLInstall_narrow(2, lpszBuf, wbuf, size_used, cbBufMax, pcbBufOut)))
|
|
||||||
{
|
|
||||||
push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HeapFree(GetProcessHeap(), 0, wbuf);
|
|
||||||
/* ignore failure; we have achieved the aim */
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
wbuf = heap_alloc(size * sizeof(WCHAR));
|
||||||
|
if (!wbuf)
|
||||||
{
|
{
|
||||||
push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
|
push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
|
||||||
ret = FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
|
ret = SQLGetInstalledDriversW(wbuf, size, &written);
|
||||||
|
if (!ret)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*sizeout = WideCharToMultiByte(CP_ACP, 0, wbuf, written, NULL, 0, NULL, NULL);
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, wbuf, written, buf, size, NULL, NULL);
|
||||||
|
|
||||||
|
heap_free(wbuf);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HKEY get_privateprofile_sectionkey(LPCWSTR section, LPCWSTR filename)
|
static HKEY get_privateprofile_sectionkey(LPCWSTR section, LPCWSTR filename)
|
||||||
|
|
Loading…
Reference in New Issue