https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d52f5b708bf6e0c8a364a…
commit d52f5b708bf6e0c8a364a7bb0433f98bfc19708b
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Mon Jun 4 03:44:04 2018 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Mon Jun 4 03:44:04 2018 +0100
[ODBCCP32] Sync with Wine Staging 3.9. CORE-14656
---
dll/win32/odbccp32/odbccp32.c | 144 ++++++++++++++++++++++--------------------
media/doc/README.WINE | 2 +-
2 files changed, 75 insertions(+), 71 deletions(-)
diff --git a/dll/win32/odbccp32/odbccp32.c b/dll/win32/odbccp32/odbccp32.c
index f9a2269345..862237c677 100644
--- a/dll/win32/odbccp32/odbccp32.c
+++ b/dll/win32/odbccp32/odbccp32.c
@@ -482,99 +482,103 @@ BOOL WINAPI SQLGetConfigMode(UWORD *pwConfigMode)
return TRUE;
}
-/* This is implemented sensibly rather than according to exact conformance to
Microsoft's buggy implementations
- * 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)
+BOOL WINAPI SQLGetInstalledDriversW(WCHAR *buf, WORD size, WORD *sizeout)
{
- HKEY hDrivers; /* Registry handle to the Drivers key */
- LONG reg_ret; /* Return code from registry functions */
- BOOL success = FALSE; /* The value we will return */
+ WORD written = 0;
+ DWORD index = 0;
+ BOOL ret = TRUE;
+ DWORD valuelen;
+ WCHAR *value;
+ HKEY drivers;
+ DWORD len;
+ LONG res;
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);
+ 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 */,
- &hDrivers)) == ERROR_SUCCESS)
+
+ res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drivers_key, 0, KEY_QUERY_VALUE,
&drivers);
+ 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);
+ push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found);
+ return FALSE;
}
- else
+
+ valuelen = 256;
+ value = heap_alloc(valuelen * sizeof(WCHAR));
+
+ size--;
+
+ while (1)
{
- /* 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);
+ len = valuelen;
+ res = RegEnumValueW(drivers, index, value, &len, NULL, NULL, NULL, NULL);
+ while (res == ERROR_MORE_DATA)
+ {
+ value = heap_realloc(value, ++len * sizeof(WCHAR));
+ 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;
+ }
+ index++;
}
- return success;
+
+ buf[written++] = 0;
+
+ heap_free(value);
+ RegCloseKey(drivers);
+ if (sizeout)
+ *sizeout = written;
+ return ret;
}
-BOOL WINAPI SQLGetInstalledDrivers(LPSTR lpszBuf, WORD cbBufMax,
- WORD *pcbBufOut)
+BOOL WINAPI SQLGetInstalledDrivers(char *buf, WORD size, WORD *sizeout)
{
+ WORD written;
+ WCHAR *wbuf;
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 (wbuf)
+ if (!buf || !size)
{
- ret = SQLGetInstalledDriversW(wbuf, size_wbuf, &size_used);
- if (ret)
- {
- 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 */
+ push_error(ODBC_ERROR_INVALID_BUFF_LEN, odbc_error_invalid_buff_len);
+ return FALSE;
}
- else
+
+ wbuf = heap_alloc(size * sizeof(WCHAR));
+ if (!wbuf)
{
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)
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index 969d46559e..829a9882a5 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -138,7 +138,7 @@ reactos/dll/win32/npptools # Synced to WineStaging-3.3
reactos/dll/win32/ntdsapi # Synced to WineStaging-3.9
reactos/dll/win32/objsel # Synced to WineStaging-3.3
reactos/dll/win32/odbc32 # Synced to WineStaging-3.3. Depends on port of
Linux ODBC.
-reactos/dll/win32/odbccp32 # Synced to WineStaging-3.3
+reactos/dll/win32/odbccp32 # Synced to WineStaging-3.9
reactos/dll/win32/ole32 # Synced to WineStaging-3.3
reactos/dll/win32/oleacc # Synced to WineStaging-3.3
reactos/dll/win32/oleaut32 # Synced to WineStaging-3.3