netsh_dns_cmd(const wchar_t *action, const wchar_t *proto, const wchar_t *if_name, const wchar_t *addr)
{
    DWORD err = 0;
    int timeout = 30000; /* in msec */
    wchar_t argv0[MAX_PATH];

    if (!addr)
    {
        if (wcscmp(action, L"delete") == 0)
        {
            addr = L"all";
        }
        else /* nothing to do -- return success*/
        {
            goto out;
        }
    }

    /* Path of netsh */
    int n = GetSystemDirectory(argv0, MAX_PATH);
    if (n > 0 && n < MAX_PATH) /* got system directory */
    {
        wcsncat(argv0, L"\\netsh.exe", MAX_PATH - n - 1);
    }
    else
    {
        wcsncpy(argv0, L"C:\\Windows\\system32\\netsh.exe", MAX_PATH);
    }

    /* cmd template:
     * netsh interface $proto $action dns $if_name $addr [validate=no]
     */
    const wchar_t *fmt = L"netsh interface %s %s dns \"%s\" %s";

    /* max cmdline length in wchars -- include room for worst case and some */
    size_t ncmdline = wcslen(fmt) + wcslen(if_name) + wcslen(addr) + 32 + 1;
    wchar_t *cmdline = malloc(ncmdline*sizeof(wchar_t));
    if (!cmdline)
    {
        err = ERROR_OUTOFMEMORY;
        goto out;
    }

    openvpn_sntprintf(cmdline, ncmdline, fmt, proto, action, if_name, addr);

    if (IsWindows7OrGreater())
    {
        wcsncat(cmdline, L" validate=no", ncmdline - wcslen(cmdline) - 1);
    }
    err = ExecCommand(argv0, cmdline, timeout);

out:
    free(cmdline);
    return err;
}
netsh_dns_cmd(const wchar_t *action, const wchar_t *proto, const wchar_t *if_name, const wchar_t *addr)
{
    DWORD err = 0;
    int timeout = 30000;  
    wchar_t argv0[MAX_PATH];

    if (!addr)
    {
        if (wcscmp(action, L"delete") == 0)
        {
            addr = L"all";
        }
        else  
        {
            goto out;
        }
    }

     
    int n = GetSystemDirectory(argv0, MAX_PATH);
    if (n > 0 && n < MAX_PATH)  
    {
        wcsncat(argv0, L"\\netsh.exe", MAX_PATH - n - 1);
    }
    else
    {
        wcsncpy(argv0, L"C:\\Windows\\system32\\netsh.exe", MAX_PATH);
    }

     
    const wchar_t *fmt = L"netsh interface %s %s dns \"%s\" %s";

     
    size_t ncmdline = wcslen(fmt) + wcslen(if_name) + wcslen(addr) + 32 + 1;
    wchar_t *cmdline = malloc(ncmdline*sizeof(wchar_t));
    if (!cmdline)
    {
        err = ERROR_OUTOFMEMORY;
        goto out;
    }

    openvpn_sntprintf(cmdline, ncmdline, fmt, proto, action, if_name, addr);

    if (IsWindows7OrGreater())
    {
        wcsncat(cmdline, L" validate=no", ncmdline - wcslen(cmdline) - 1);
    }
    err = ExecCommand(argv0, cmdline, timeout);

out:
    free(cmdline);
    return err;
}