[v3 PATCH] odbccp32: Implement SQLRemoveDriver/SQLRemoveDriverW

Huw Davies huw at codeweavers.com
Thu Mar 16 03:42:31 CDT 2017


On Thu, Mar 16, 2017 at 04:54:08AM +0000, Alistair Leslie-Hughes wrote:
> v2 - Support Usage Count.
> v3 - Write key when not zero.
> 
> Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
> ---
>  dlls/odbccp32/odbccp32.c   | 66 +++++++++++++++++++++++++++++++++++++++++-----
>  dlls/odbccp32/tests/misc.c |  4 +--
>  2 files changed, 61 insertions(+), 9 deletions(-)
> 
> diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c
> index 037a2a9..ace801f 100644
> --- a/dlls/odbccp32/odbccp32.c
> +++ b/dlls/odbccp32/odbccp32.c
> @@ -1132,22 +1132,74 @@ BOOL WINAPI SQLRemoveDefaultDataSource(void)
>      return FALSE;
>  }
>  
> -BOOL WINAPI SQLRemoveDriverW(LPCWSTR lpszDriver, BOOL fRemoveDSN,
> -               LPDWORD lpdwUsageCount)
> +BOOL WINAPI SQLRemoveDriverW(LPCWSTR drivername, BOOL remove_dsn, LPDWORD usage_count)
>  {
> +    HKEY hkey;
> +    DWORD usagecount = 1;
> +
>      clear_errors();
> -    FIXME("%s %d %p\n", debugstr_w(lpszDriver), fRemoveDSN, lpdwUsageCount);
> -    if (lpdwUsageCount) *lpdwUsageCount = 1;
> +    TRACE("%s %d %p\n", debugstr_w(drivername), remove_dsn, usage_count);
> +
> +    if (RegOpenKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey) == ERROR_SUCCESS)
> +    {
> +        HKEY hkeydriver;
> +
> +        if (RegOpenKeyW(hkey, drivername, &hkeydriver) == ERROR_SUCCESS)
> +        {
> +            DWORD size, type;
> +
> +            size = sizeof(usagecount);
> +            RegGetValueA(hkeydriver, NULL, "UsageCount", RRF_RT_DWORD, &type, &usagecount, &size);
> +            TRACE("Usage count %d\n", usagecount);
> +        }
> +
> +        if (usagecount)
> +            usagecount--;
> +
> +        if (!usagecount)
> +        {
> +            RegCloseKey(hkeydriver);
> +
> +            if (RegDeleteKeyW(hkey, drivername) != ERROR_SUCCESS)
> +                ERR("Failed to delete registry key: %s\n", debugstr_w(drivername));
> +
> +            if (RegOpenKeyW(hkey, odbcdrivers, &hkeydriver) == ERROR_SUCCESS)
> +            {
> +                if(RegDeleteValueW(hkeydriver, drivername) != ERROR_SUCCESS)
> +                    ERR("Failed to delete registry value: %s\n", debugstr_w(drivername));
> +            }
> +        }
> +        else
> +        {
> +            if (RegSetValueExA(hkeydriver, "UsageCount", 0, REG_DWORD, (BYTE*)&usagecount, sizeof(usagecount)) != ERROR_SUCCESS)
> +                ERR("Failed to write registry UsageCount key\n");
> +        }
> +        RegCloseKey(hkeydriver);
> +
> +        RegCloseKey(hkey);
> +    }
> +
> +    if (usage_count)
> +        *usage_count = usagecount;
> +
>      return TRUE;
>  }

This isn't correct if RegOpenKeyW(hkey, drivername, &hkeydriver) fails.

The clue that something is wrong (at least for this style of handling
errors) is the two RegCloseKey()s in the same block.

Huw.



More information about the wine-devel mailing list