[1/5] winhttp: Support setting and querying credentials on request handles.

Hans Leidekker hans at codeweavers.com
Thu Apr 22 09:34:48 CDT 2010


---
 dlls/winhttp/session.c       |   78 ++++++++++++++++++++++++++-
 dlls/winhttp/tests/winhttp.c |  123 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 199 insertions(+), 2 deletions(-)

diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index cd5ebed..82da721 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -547,6 +547,18 @@ static void request_destroy( object_header_t *hdr )
     heap_free( request );
 }
 
+static void str_to_buffer( WCHAR *buffer, const WCHAR *str, LPDWORD buflen )
+{
+    int len = 0;
+    if (str) len = strlenW( str );
+    if (buffer && *buflen > len)
+    {
+        memcpy( buffer, str, len * sizeof(WCHAR) );
+        buffer[len] = 0;
+    }
+    *buflen = len * sizeof(WCHAR);
+}
+
 static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen )
 {
     request_t *request = (request_t *)hdr;
@@ -615,6 +627,23 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf
         *(DWORD *)buffer = request->recv_timeout;
         *buflen = sizeof(DWORD);
         return TRUE;
+
+    case WINHTTP_OPTION_USERNAME:
+        str_to_buffer( buffer, request->connect->username, buflen );
+        return TRUE;
+
+    case WINHTTP_OPTION_PASSWORD:
+        str_to_buffer( buffer, request->connect->password, buflen );
+        return TRUE;
+
+    case WINHTTP_OPTION_PROXY_USERNAME:
+        str_to_buffer( buffer, request->connect->session->proxy_username, buflen );
+        return TRUE;
+
+    case WINHTTP_OPTION_PROXY_PASSWORD:
+        str_to_buffer( buffer, request->connect->session->proxy_password, buflen );
+        return TRUE;
+
     default:
         FIXME("unimplemented option %u\n", option);
         set_last_error( ERROR_INVALID_PARAMETER );
@@ -622,6 +651,19 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf
     }
 }
 
+static WCHAR *buffer_to_str( WCHAR *buffer, DWORD buflen )
+{
+    WCHAR *ret;
+    if ((ret = heap_alloc( (buflen + 1) * sizeof(WCHAR))))
+    {
+        memcpy( ret, buffer, buflen * sizeof(WCHAR) );
+        ret[buflen] = 0;
+        return ret;
+    }
+    set_last_error( ERROR_OUTOFMEMORY );
+    return NULL;
+}
+
 static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD buflen )
 {
     request_t *request = (request_t *)hdr;
@@ -681,8 +723,7 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
         return TRUE;
     }
     case WINHTTP_OPTION_SECURITY_FLAGS:
-        FIXME("WINHTTP_OPTION_SECURITY_FLAGS unimplemented (%08x)\n",
-              *(DWORD *)buffer);
+        FIXME("WINHTTP_OPTION_SECURITY_FLAGS unimplemented (%08x)\n", *(DWORD *)buffer);
         return TRUE;
     case WINHTTP_OPTION_RESOLVE_TIMEOUT:
         request->resolve_timeout = *(DWORD *)buffer;
@@ -696,6 +737,39 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
     case WINHTTP_OPTION_RECEIVE_TIMEOUT:
         request->recv_timeout = *(DWORD *)buffer;
         return TRUE;
+
+    case WINHTTP_OPTION_USERNAME:
+    {
+        connect_t *connect = request->connect;
+
+        heap_free( connect->username );
+        if (!(connect->username = buffer_to_str( buffer, buflen ))) return FALSE;
+        return TRUE;
+    }
+    case WINHTTP_OPTION_PASSWORD:
+    {
+        connect_t *connect = request->connect;
+
+        heap_free( connect->password );
+        if (!(connect->password = buffer_to_str( buffer, buflen ))) return FALSE;
+        return TRUE;
+    }
+    case WINHTTP_OPTION_PROXY_USERNAME:
+    {
+        session_t *session = request->connect->session;
+
+        heap_free( session->proxy_username );
+        if (!(session->proxy_username = buffer_to_str( buffer, buflen ))) return FALSE;
+        return TRUE;
+    }
+    case WINHTTP_OPTION_PROXY_PASSWORD:
+    {
+        session_t *session = request->connect->session;
+
+        heap_free( session->proxy_password );
+        if (!(session->proxy_password = buffer_to_str( buffer, buflen ))) return FALSE;
+        return TRUE;
+    }
     default:
         FIXME("unimplemented option %u\n", option);
         set_last_error( ERROR_INVALID_PARAMETER );
diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c
index 94346e2..9d3a473 100644
--- a/dlls/winhttp/tests/winhttp.c
+++ b/dlls/winhttp/tests/winhttp.c
@@ -1677,6 +1677,128 @@ static void test_resolve_timeout(void)
     WinHttpCloseHandle(ses);
 }
 
+static void test_credentials(void)
+{
+    static const WCHAR hostnameW[] = {'l','o','c','a','l','h','o','s','t',0};
+    static WCHAR userW[] = {'u','s','e','r',0};
+    static WCHAR passW[] = {'p','a','s','s',0};
+    static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
+    static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
+    HANDLE ses, con, req;
+    DWORD size, error;
+    WCHAR buffer[32];
+    BOOL ret;
+
+    ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
+    ok(ses != NULL, "failed to open session %u\n", GetLastError());
+
+    con = WinHttpConnect(ses, hostnameW, 0, 0);
+    ok(con != NULL, "failed to open a connection %u\n", GetLastError());
+
+    req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
+    ok(req != NULL, "failed to open a request %u\n", GetLastError());
+
+    size = sizeof(buffer)/sizeof(WCHAR);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
+    ok(ret, "failed to query proxy username %u\n", GetLastError());
+    ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
+    ok(!size, "expected 0, got %u\n", size);
+
+    size = sizeof(buffer)/sizeof(WCHAR);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
+    ok(ret, "failed to query proxy password %u\n", GetLastError());
+    ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
+    ok(!size, "expected 0, got %u\n", size);
+
+    ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
+    ok(ret, "failed to set username %u\n", GetLastError());
+
+    size = sizeof(buffer)/sizeof(WCHAR);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
+    ok(ret, "failed to query proxy username %u\n", GetLastError());
+    ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
+    ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
+
+    size = sizeof(buffer)/sizeof(WCHAR);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
+    ok(ret, "failed to query username %u\n", GetLastError());
+    ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
+    ok(!size, "expected 0, got %u\n", size);
+
+    size = sizeof(buffer)/sizeof(WCHAR);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
+    ok(ret, "failed to query password %u\n", GetLastError());
+    ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
+    ok(!size, "expected 0, got %u\n", size);
+
+    ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
+    ok(ret, "failed to set proxy password %u\n", GetLastError());
+
+    size = sizeof(buffer)/sizeof(WCHAR);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
+    ok(ret, "failed to query proxy password %u\n", GetLastError());
+    ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
+    ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
+
+    ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
+    ok(ret, "failed to set username %u\n", GetLastError());
+
+    size = sizeof(buffer)/sizeof(WCHAR);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
+    ok(ret, "failed to query username %u\n", GetLastError());
+    ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
+    ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
+
+    ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
+    ok(ret, "failed to set password %u\n", GetLastError());
+
+    size = sizeof(buffer)/sizeof(WCHAR);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
+    ok(ret, "failed to query password %u\n", GetLastError());
+    ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
+    ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
+
+    WinHttpCloseHandle(req);
+
+    req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
+    ok(req != NULL, "failed to open a request %u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
+
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
+    error = GetLastError();
+    ok(!ret, "expected failure\n");
+    ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
+
+    ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
+    ok(ret, "failed to set credentials %u\n", GetLastError());
+
+    size = sizeof(buffer)/sizeof(WCHAR);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
+    ok(ret, "failed to query username %u\n", GetLastError());
+    todo_wine {
+    ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
+    ok(!size, "expected 0, got %u\n", size);
+    }
+
+    size = sizeof(buffer)/sizeof(WCHAR);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
+    ok(ret, "failed to query password %u\n", GetLastError());
+    todo_wine {
+    ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
+    ok(!size, "expected 0, got %u\n", size);
+    }
+
+    WinHttpCloseHandle(req);
+    WinHttpCloseHandle(con);
+    WinHttpCloseHandle(ses);
+}
+
 START_TEST (winhttp)
 {
     test_OpenRequest();
@@ -1691,4 +1813,5 @@ START_TEST (winhttp)
     test_empty_headers_param();
     test_Timeouts();
     test_resolve_timeout();
+    test_credentials();
 }
-- 
1.7.0.4







More information about the wine-patches mailing list