https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d52f5b708bf6e0c8a364a7bb0433f98bfc19708b

commit d52f5b708bf6e0c8a364a7bb0433f98bfc19708b
Author:     Amine Khaldi <[email protected]>
AuthorDate: Mon Jun 4 03:44:04 2018 +0100
Commit:     Amine Khaldi <[email protected]>
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

Reply via email to