[v2 PATCH 3/3] odbccp32: Implement SQLConfigDriver/W

Huw Davies huw at codeweavers.com
Tue Apr 4 03:14:48 CDT 2017


On Wed, Mar 22, 2017 at 10:06:29PM +0000, Alistair Leslie-Hughes wrote:
> v2 - No Changes
> 
> Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
> ---
>  dlls/odbccp32/odbccp32.c | 125 +++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 115 insertions(+), 10 deletions(-)
> 
> diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c
> index d95a110..f327817 100644
> --- a/dlls/odbccp32/odbccp32.c
> +++ b/dlls/odbccp32/odbccp32.c
> @@ -63,6 +63,9 @@ static const WCHAR odbc_error_out_of_mem[] = {'O','u','t',' ','o','f',' ','m','e
>  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};
>  static const WCHAR odbc_error_invalid_param_string[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','t','r','i','n','g',0};
>  
> +static BOOL (WINAPI *pConfigDriverW)(HWND hwnd, WORD request, const WCHAR *driver, const WCHAR *args, const WCHAR *msg, WORD msgmax, WORD *msgout);
> +static BOOL (WINAPI *pConfigDriverA)(HWND hwnd, WORD request, const char *driver, const char *args, const char *msg, WORD msgmax, WORD *msgout);
> +
>  /* Push an error onto the error stack, taking care of ranges etc. */
>  static void push_error(int code, LPCWSTR msg)
>  {
> @@ -248,22 +251,124 @@ BOOL WINAPI SQLConfigDataSource(HWND hwndParent, WORD fRequest,
>      return TRUE;
>  }
>  
> -BOOL WINAPI SQLConfigDriverW(HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver,
> -               LPCWSTR lpszArgs, LPWSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut)
> +BOOL WINAPI SQLConfigDriverW(HWND hwnd, WORD request, LPCWSTR driver,
> +               LPCWSTR args, LPWSTR msg, WORD msgmax, WORD *msgout)
>  {
> +    static WCHAR reg_driver[] = {'d','r','i','v','e','r',0};
> +    long ret;
> +    HMODULE hmod;
> +    HKEY hkey;
> +    WCHAR *filename = NULL;
> +    DWORD size = 0, type;
> +    BOOL funcret = FALSE;
> +
>      clear_errors();
> -    FIXME("(%p %d %s %s %p %d %p)\n", hwndParent, fRequest, debugstr_w(lpszDriver),
> -          debugstr_w(lpszArgs), lpszMsg, cbMsgMax, pcbMsgOut);
> -    return TRUE;
> +    TRACE("(%p %d %s %s %p %d %p)\n", hwnd, request, debugstr_w(driver),
> +          debugstr_w(args), msg, msgmax, msgout);
> +
> +    if ((ret = RegOpenKeyW(HKEY_CURRENT_USER, odbcini, &hkey)) == ERROR_SUCCESS)
> +    {
> +        HKEY hkeydriver;
> +
> +        if ((ret = RegOpenKeyW(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
> +        {
> +            ret = RegGetValueW(hkeydriver, NULL, reg_driver, RRF_RT_REG_SZ, &type, NULL, &size);
> +            if(ret == ERROR_MORE_DATA)
> +            {
> +                filename = HeapAlloc(GetProcessHeap(), 0, size);
> +                if(!filename)
> +                {
> +                    RegCloseKey(hkeydriver);
> +                    RegCloseKey(hkey);
> +                    return ODBC_ERROR_OUT_OF_MEM;
> +                }
> +                ret = RegGetValueW(hkeydriver, NULL, driver, RRF_RT_REG_SZ, &type, filename, &size);
> +            }
> +
> +            RegCloseKey(hkeydriver);
> +        }
> +
> +        RegCloseKey(hkey);
> +    }
> +
> +    if(ret != ERROR_SUCCESS)
> +    {
> +        HeapFree(GetProcessHeap(), 0, filename);
> +        return ODBC_ERROR_INVALID_DSN;
> +    }
> +
> +    hmod = LoadLibraryW(filename);
> +    HeapFree(GetProcessHeap(), 0, filename);

This function is supposed to return a BOOL, so either that's actually
not the case, or these errors should be set using SetLastError().

I suggest you try writing a helper that could be used by both A and W
versions.

Something like:
HMODULE load_driver(const WCHAR *driver)

(or
DWORD load_driver(const WCHAR *driver, HMODULE *mod)
if you need to return the error code.)

Feel free to pick a better function name.

Huw.



More information about the wine-devel mailing list