winhttp: Add some tests for set/query option, make them pass under Wine.

Dmitry Timoshkov dmitry at codeweavers.com
Tue Sep 16 04:51:58 CDT 2008


---
 dlls/winhttp/session.c       |  132 ++++++++++++++++++++++++++++++++++---
 dlls/winhttp/tests/winhttp.c |  150 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 271 insertions(+), 11 deletions(-)

diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index 927c347..4bf9d43 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -76,8 +76,44 @@ static void session_destroy( object_header_t *hdr )
     heap_free( session );
 }
 
+static BOOL session_query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen )
+{
+    if (!buflen)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    switch (option)
+    {
+    case WINHTTP_OPTION_REDIRECT_POLICY:
+    {
+        if (!buffer || *buflen < sizeof(DWORD))
+        {
+            *buflen = sizeof(DWORD);
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
+
+        *(DWORD *)buffer = hdr->redirect_policy;
+        *buflen = sizeof(DWORD);
+        return TRUE;
+    }
+    default:
+        FIXME("unimplemented option %u\n", option);
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+}
+
 static BOOL session_set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD buflen )
 {
+    if (!buffer)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
     switch (option)
     {
     case WINHTTP_OPTION_PROXY:
@@ -89,22 +125,33 @@ static BOOL session_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
     }
     case WINHTTP_OPTION_REDIRECT_POLICY:
     {
-        DWORD policy = *(DWORD *)buffer;
+        DWORD policy;
 
+        if (buflen != sizeof(policy))
+        {
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
+
+        policy = *(DWORD *)buffer;
         TRACE("0x%x\n", policy);
         hdr->redirect_policy = policy;
         return TRUE;
     }
+    case WINHTTP_OPTION_DISABLE_FEATURE:
+        SetLastError(ERROR_WINHTTP_INCORRECT_HANDLE_TYPE);
+        return FALSE;
     default:
         FIXME("unimplemented option %u\n", option);
-        return TRUE;
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
     }
 }
 
 static const object_vtbl_t session_vtbl =
 {
     session_destroy,
-    NULL,
+    session_query_option,
     session_set_option
 };
 
@@ -125,6 +172,7 @@ HINTERNET WINAPI WinHttpOpen( LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWST
     session->hdr.flags = flags;
     session->hdr.refs = 1;
     session->access = access;
+    session->hdr.redirect_policy = WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP;
 
     if (agent && !(session->agent = strdupW( agent ))) goto end;
     if (proxy && !(session->proxy_server = strdupW( proxy ))) goto end;
@@ -254,15 +302,29 @@ static void request_destroy( object_header_t *hdr )
 
 static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen )
 {
+    if (!buflen)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
     switch (option)
     {
     case WINHTTP_OPTION_SECURITY_FLAGS:
     {
-        DWORD flags = 0;
+        DWORD flags;
 
+        if (!buffer || *buflen < sizeof(flags))
+        {
+            *buflen = sizeof(flags);
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
+
+        flags = 0;
         if (hdr->flags & WINHTTP_FLAG_SECURE) flags |= SECURITY_FLAG_SECURE;
         *(DWORD *)buffer = flags;
-        *buflen = sizeof(DWORD);
+        *buflen = sizeof(flags);
         return TRUE;
     }
     case WINHTTP_OPTION_SERVER_CERT_CONTEXT:
@@ -270,6 +332,13 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf
         const CERT_CONTEXT *cert;
         request_t *request = (request_t *)hdr;
 
+        if (!buffer || *buflen < sizeof(cert))
+        {
+            *buflen = sizeof(cert);
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
+
         if (!(cert = netconn_get_certificate( &request->netconn ))) return FALSE;
         *(CERT_CONTEXT **)buffer = (CERT_CONTEXT *)cert;
         *buflen = sizeof(cert);
@@ -277,18 +346,32 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf
     }
     case WINHTTP_OPTION_SECURITY_KEY_BITNESS:
     {
+        if (!buffer || *buflen < sizeof(DWORD))
+        {
+            *buflen = sizeof(DWORD);
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
+
         *(DWORD *)buffer = 128; /* FIXME */
         *buflen = sizeof(DWORD);
         return TRUE;
     }
     default:
         FIXME("unimplemented option %u\n", option);
+        SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 }
 
 static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD buflen )
 {
+    if (!buffer)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
     switch (option)
     {
     case WINHTTP_OPTION_PROXY:
@@ -302,6 +385,12 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
     {
         DWORD disable = *(DWORD *)buffer;
 
+        if (buflen != sizeof(DWORD))
+        {
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
+
         TRACE("0x%x\n", disable);
         hdr->disable_flags &= disable;
         return TRUE;
@@ -310,6 +399,12 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
     {
         DWORD policy = *(DWORD *)buffer;
 
+        if (buflen != sizeof(DWORD))
+        {
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
+
         TRACE("0x%x\n", policy);
         hdr->logon_policy = policy;
         return TRUE;
@@ -318,12 +413,19 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
     {
         DWORD policy = *(DWORD *)buffer;
 
+        if (buflen != sizeof(DWORD))
+        {
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
+
         TRACE("0x%x\n", policy);
         hdr->redirect_policy = policy;
         return TRUE;
     }
     default:
         FIXME("unimplemented option %u\n", option);
+        SetLastError(ERROR_INVALID_PARAMETER);
         return TRUE;
     }
 }
@@ -426,10 +528,14 @@ static BOOL query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPD
         return TRUE;
     }
     default:
-    {
         if (hdr->vtbl->query_option) ret = hdr->vtbl->query_option( hdr, option, buffer, buflen );
-        else FIXME("unimplemented option %u\n", option);
-    }
+        else
+        {
+            FIXME("unimplemented option %u\n", option);
+            SetLastError(ERROR_WINHTTP_INCORRECT_HANDLE_TYPE);
+            return FALSE;
+        }
+        break;
     }
     return ret;
 }
@@ -468,10 +574,14 @@ static BOOL set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD
         return TRUE;
     }
     default:
-    {
         if (hdr->vtbl->set_option) ret = hdr->vtbl->set_option( hdr, option, buffer, buflen );
-        else FIXME("unimplemented option %u\n", option);
-    }
+        else
+        {
+            FIXME("unimplemented option %u\n", option);
+            SetLastError(ERROR_WINHTTP_INCORRECT_HANDLE_TYPE);
+            return FALSE;
+        }
+        break;
     }
     return ret;
 }
diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c
index 7914805..a4e33b4 100644
--- a/dlls/winhttp/tests/winhttp.c
+++ b/dlls/winhttp/tests/winhttp.c
@@ -31,6 +31,154 @@ static const WCHAR test_useragent[] =
     {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
 static const WCHAR test_server[] = {'w','i','n','e','h','q','.','o','r','g',0};
 
+static void test_QueryOption(void)
+{
+    BOOL ret;
+    HINTERNET session, request, connection;
+    DWORD feature, size;
+
+    SetLastError(0xdeadbeef);
+    session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
+    ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
+    ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_PARAMETER,
+       "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+
+    size = 0xdeadbeef;
+    SetLastError(0xdeadbeef);
+    ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
+    ok(!ret, "should fail to query option\n");
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+       "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
+    ok(size == 4, "expected 4, got %u\n", size);
+
+    feature = 0xdeadbeef;
+    size = sizeof(feature) - 1;
+    SetLastError(0xdeadbeef);
+    ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
+    ok(!ret, "should fail to query option\n");
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+       "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
+    ok(size == 4, "expected 4, got %u\n", size);
+
+    feature = 0xdeadbeef;
+    size = sizeof(feature) + 1;
+    SetLastError(0xdeadbeef);
+    ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
+    ok(ret, "failed to query option %u\n", GetLastError());
+    ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
+    ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
+       "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
+
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
+    ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
+    ok(GetLastError() == ERROR_INVALID_PARAMETER,
+       "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+
+    feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
+    ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+       "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
+
+    feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
+    ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+       "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
+
+    feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
+    ok(ret, "failed to set redirect policy %u\n", GetLastError());
+
+    feature = 0xdeadbeef;
+    size = sizeof(feature);
+    SetLastError(0xdeadbeef);
+    ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
+    ok(ret, "failed to query option %u\n", GetLastError());
+    ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
+       "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
+
+    feature = WINHTTP_DISABLE_COOKIES;
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
+    ok(!ret, "should fail to set disable feature for a session\n");
+    ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
+       "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    connection = WinHttpConnect(session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
+    ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
+
+    feature = WINHTTP_DISABLE_COOKIES;
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
+    ok(!ret, "should fail to set disable feature for a connection\n");
+    ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
+       "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
+                                 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
+    if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
+    {
+        skip("Network unreachable, skipping the test\n");
+        goto done;
+    }
+
+    feature = 0xdeadbeef;
+    size = sizeof(feature);
+    SetLastError(0xdeadbeef);
+    ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
+    ok(!ret, "should fail to query disable feature for a request\n");
+    ok(GetLastError() == ERROR_INVALID_PARAMETER,
+       "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+
+    feature = 0;
+    size = sizeof(feature);
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
+    ok(ret, "failed to set feature %u\n", GetLastError());
+
+    feature = 0xffffffff;
+    size = sizeof(feature);
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
+    ok(ret, "failed to set feature %u\n", GetLastError());
+
+    feature = WINHTTP_DISABLE_COOKIES;
+    size = sizeof(feature);
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
+    ok(ret, "failed to set feature %u\n", GetLastError());
+
+    size = 0;
+    SetLastError(0xdeadbeef);
+    ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
+    ok(!ret, "should fail to query disable feature for a request\n");
+    ok(GetLastError() == ERROR_INVALID_PARAMETER,
+       "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = WinHttpCloseHandle(request);
+    ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
+
+done:
+    SetLastError(0xdeadbeef);
+    ret = WinHttpCloseHandle(connection);
+    ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
+    SetLastError(0xdeadbeef);
+    ret = WinHttpCloseHandle(session);
+    ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
+}
+
 static void test_OpenRequest (void)
 {
     BOOL ret;
@@ -273,6 +421,7 @@ static void test_WinHttpAddHeaders(void)
      */
     index = 0;
     len = 5*sizeof(WCHAR);
+    memset(check_buffer, 0xab, sizeof(check_buffer));
     memcpy(buffer, check_buffer, sizeof(buffer));
     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
         test_header_name, buffer, &len, &index);
@@ -677,4 +826,5 @@ START_TEST (winhttp)
     test_WinHttpAddHeaders();
     test_secure_connection();
     test_request_parameter_defaults();
+    test_QueryOption();
 }
-- 
1.6.0.1






More information about the wine-patches mailing list