From 11da0ac8a79b0a189f1ef3e58cdbb72b4b41d1a2 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Tue, 16 Sep 2008 18:51:58 +0900 Subject: [PATCH] winhttp: Add some tests for set/query option, make them pass under Wine. --- 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 927c34708a8..4bf9d434745 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 79148053309..a4e33b47086 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(); } -- 2.11.4.GIT