[URLMON_WINETEST] Sync with Wine Staging 2.2. CORE-12823
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 19 Mar 2017 16:58:47 +0000 (16:58 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 19 Mar 2017 16:58:47 +0000 (16:58 +0000)
svn path=/trunk/; revision=74196

rostests/winetests/urlmon/protocol.c
rostests/winetests/urlmon/sec_mgr.c
rostests/winetests/urlmon/uri.c
rostests/winetests/urlmon/url.c

index 096768d..7c85c7d 100644 (file)
@@ -1121,6 +1121,12 @@ static IInternetProtocolSink protocol_sink = { &protocol_sink_vtbl };
 
 static HRESULT WINAPI MimeProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
 {
 
 static HRESULT WINAPI MimeProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
 {
+    if(IsEqualGUID(&IID_IUnknown, riid)
+            || IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
+        *ppv = iface;
+        return S_OK;
+    }
+
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
index 20faff9..3bb4a3e 100644 (file)
@@ -766,7 +766,7 @@ static const zone_domain_mapping zone_domain_mappings[] = {
     {"wine.testing",NULL,"*",URLZONE_CUSTOM2}
 };
 
     {"wine.testing",NULL,"*",URLZONE_CUSTOM2}
 };
 
-static void register_zone_domains(void)
+static BOOL register_zone_domains(void)
 {
     HKEY domains;
     DWORD res, i;
 {
     HKEY domains;
     DWORD res, i;
@@ -779,6 +779,12 @@ static void register_zone_domains(void)
         DWORD zone = URLZONE_CUSTOM;
 
         res = RegCreateKeyA(domains, "local.machine", &domain);
         DWORD zone = URLZONE_CUSTOM;
 
         res = RegCreateKeyA(domains, "local.machine", &domain);
+        if (res == ERROR_ACCESS_DENIED)
+        {
+            skip("need admin rights\n");
+            RegCloseKey(domains);
+            return FALSE;
+        }
         ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
 
         res = RegSetValueExA(domain, "http", 0, REG_DWORD, (BYTE*)&zone, sizeof(DWORD));
         ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
 
         res = RegSetValueExA(domain, "http", 0, REG_DWORD, (BYTE*)&zone, sizeof(DWORD));
@@ -818,6 +824,7 @@ static void register_zone_domains(void)
     }
 
     RegCloseKey(domains);
     }
 
     RegCloseKey(domains);
+    return TRUE;
 }
 
 static void unregister_zone_domains(void)
 }
 
 static void unregister_zone_domains(void)
@@ -972,7 +979,7 @@ static void test_zone_domains(void)
 
     test_zone_domain_cache();
 
 
     test_zone_domain_cache();
 
-    register_zone_domains();
+    if (!register_zone_domains()) return;
     run_child_process();
     unregister_zone_domains();
 }
     run_child_process();
     unregister_zone_domains();
 }
index 9e0b2c3..318727d 100644 (file)
@@ -122,6 +122,8 @@ typedef struct _uri_str_property {
     HRESULT     expected;
     BOOL        todo;
     const char* broken_value;
     HRESULT     expected;
     BOOL        todo;
     const char* broken_value;
+    const char* value2;
+    HRESULT     expected2;
 } uri_str_property;
 
 typedef struct _uri_dword_property {
 } uri_str_property;
 
 typedef struct _uri_dword_property {
@@ -1964,7 +1966,7 @@ static const uri_properties uri_tests[] = {
             {"http://google.com.uk/",S_OK,FALSE},
             {"google.com.uk",S_OK,FALSE},
             {"http://google.com.uk/",S_OK,FALSE},
             {"http://google.com.uk/",S_OK,FALSE},
             {"google.com.uk",S_OK,FALSE},
             {"http://google.com.uk/",S_OK,FALSE},
-            {"google.com.uk",S_OK,FALSE},
+            {"google.com.uk",S_OK,FALSE,NULL,"com.uk",S_OK},  /* cf. google.co.uk below */
             {"",S_FALSE,FALSE},
             {"",S_FALSE,FALSE},
             {"google.com.uk",S_OK,FALSE},
             {"",S_FALSE,FALSE},
             {"",S_FALSE,FALSE},
             {"google.com.uk",S_OK,FALSE},
@@ -1984,6 +1986,31 @@ static const uri_properties uri_tests[] = {
             {URLZONE_INVALID,E_NOTIMPL,FALSE}
         }
     },
             {URLZONE_INVALID,E_NOTIMPL,FALSE}
         }
     },
+    {   "http://google.co.uk", 0, S_OK, FALSE,
+        {
+            {"http://google.co.uk/",S_OK,FALSE},
+            {"google.co.uk",S_OK,FALSE},
+            {"http://google.co.uk/",S_OK,FALSE},
+            {"google.co.uk",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"google.co.uk",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"/",S_OK,FALSE},
+            {"/",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"http://google.co.uk",S_OK,FALSE},
+            {"http",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE}
+        },
+        {
+            {Uri_HOST_DNS,S_OK,FALSE},
+            {80,S_OK,FALSE},
+            {URL_SCHEME_HTTP,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE}
+        }
+    },
     {   "http://google.com.com", 0, S_OK, FALSE,
         {
             {"http://google.com.com/",S_OK,FALSE},
     {   "http://google.com.com", 0, S_OK, FALSE,
         {
             {"http://google.com.com/",S_OK,FALSE},
@@ -2014,7 +2041,7 @@ static const uri_properties uri_tests[] = {
             {"http://google.uk.1/",S_OK,FALSE},
             {"google.uk.1",S_OK,FALSE},
             {"http://google.uk.1/",S_OK,FALSE},
             {"http://google.uk.1/",S_OK,FALSE},
             {"google.uk.1",S_OK,FALSE},
             {"http://google.uk.1/",S_OK,FALSE},
-            {"google.uk.1",S_OK,FALSE},
+            {"google.uk.1",S_OK,FALSE,NULL,"uk.1",S_OK},
             {"",S_FALSE,FALSE},
             {"",S_FALSE,FALSE},
             {"google.uk.1",S_OK,FALSE},
             {"",S_FALSE,FALSE},
             {"",S_FALSE,FALSE},
             {"google.uk.1",S_OK,FALSE},
@@ -2090,7 +2117,7 @@ static const uri_properties uri_tests[] = {
             {"http://.uk/",S_OK,FALSE},
             {".uk",S_OK,FALSE},
             {"http://.uk/",S_OK,FALSE},
             {"http://.uk/",S_OK,FALSE},
             {".uk",S_OK,FALSE},
             {"http://.uk/",S_OK,FALSE},
-            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE,NULL,".uk",S_OK},
             {"",S_FALSE,FALSE},
             {"",S_FALSE,FALSE},
             {".uk",S_OK,FALSE},
             {"",S_FALSE,FALSE},
             {"",S_FALSE,FALSE},
             {".uk",S_OK,FALSE},
@@ -2115,7 +2142,7 @@ static const uri_properties uri_tests[] = {
             {"http://www.co.google.com.[]/",S_OK,FALSE},
             {"www.co.google.com.[]",S_OK,FALSE},
             {"http://www.co.google.com.[]/",S_OK,FALSE},
             {"http://www.co.google.com.[]/",S_OK,FALSE},
             {"www.co.google.com.[]",S_OK,FALSE},
             {"http://www.co.google.com.[]/",S_OK,FALSE},
-            {"google.com.[]",S_OK,FALSE},
+            {"google.com.[]",S_OK,FALSE,NULL,"com.[]",S_OK},
             {"",S_FALSE,FALSE},
             {"",S_FALSE,FALSE},
             {"www.co.google.com.[]",S_OK,FALSE},
             {"",S_FALSE,FALSE},
             {"",S_FALSE,FALSE},
             {"www.co.google.com.[]",S_OK,FALSE},
@@ -7325,6 +7352,7 @@ typedef struct _uri_parse_test {
     const char  *property;
     HRESULT     expected;
     BOOL        todo;
     const char  *property;
     HRESULT     expected;
     BOOL        todo;
+    const char  *property2;
 } uri_parse_test;
 
 static const uri_parse_test uri_parse_tests[] = {
 } uri_parse_test;
 
 static const uri_parse_test uri_parse_tests[] = {
@@ -7388,7 +7416,7 @@ static const uri_parse_test uri_parse_tests[] = {
     {"file://server/test",0,PARSE_SITE,0,"server",S_OK,FALSE},
 
     /* PARSE_DOMAIN tests. */
     {"file://server/test",0,PARSE_SITE,0,"server",S_OK,FALSE},
 
     /* PARSE_DOMAIN tests. */
-    {"http://google.com.uk/",0,PARSE_DOMAIN,0,"google.com.uk",S_OK,FALSE},
+    {"http://google.com.uk/",0,PARSE_DOMAIN,0,"google.com.uk",S_OK,FALSE,"com.uk"},
     {"http://google.com.com/",0,PARSE_DOMAIN,0,"com.com",S_OK,FALSE},
     {"test/test",Uri_CREATE_ALLOW_RELATIVE,PARSE_DOMAIN,0,"",S_OK,FALSE},
     {"file://server/test",0,PARSE_DOMAIN,0,"",S_OK,FALSE},
     {"http://google.com.com/",0,PARSE_DOMAIN,0,"com.com",S_OK,FALSE},
     {"test/test",Uri_CREATE_ALLOW_RELATIVE,PARSE_DOMAIN,0,"",S_OK,FALSE},
     {"file://server/test",0,PARSE_DOMAIN,0,"",S_OK,FALSE},
@@ -7412,6 +7440,11 @@ static inline LPWSTR a2w(LPCSTR str) {
     return ret;
 }
 
     return ret;
 }
 
+static inline void *heap_alloc(size_t len)
+{
+    return HeapAlloc(GetProcessHeap(), 0, len);
+}
+
 static inline BOOL heap_free(void* mem) {
     return HeapFree(GetProcessHeap(), 0, mem);
 }
 static inline BOOL heap_free(void* mem) {
     return HeapFree(GetProcessHeap(), 0, mem);
 }
@@ -7617,9 +7650,12 @@ static void test_IUri_GetPropertyBSTR(void) {
 
                 hr = IUri_GetPropertyBSTR(uri, j, &received, 0);
                 todo_wine_if(prop.todo) {
 
                 hr = IUri_GetPropertyBSTR(uri, j, &received, 0);
                 todo_wine_if(prop.todo) {
-                    ok(hr == prop.expected, "GetPropertyBSTR returned 0x%08x, expected 0x%08x. On uri_tests[%d].str_props[%d].\n",
+                    ok(hr == prop.expected ||
+                       (prop.value2 && hr == prop.expected2),
+                       "GetPropertyBSTR returned 0x%08x, expected 0x%08x. On uri_tests[%d].str_props[%d].\n",
                             hr, prop.expected, i, j);
                             hr, prop.expected, i, j);
-                    ok(!strcmp_aw(prop.value, received) || broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
+                    ok(!strcmp_aw(prop.value, received) || (prop.value2 && !strcmp_aw(prop.value2, received)) ||
+                       broken(prop.broken_value && !strcmp_aw(prop.broken_value, received)),
                             "Expected %s but got %s on uri_tests[%d].str_props[%d].\n",
                             prop.value, wine_dbgstr_w(received), i, j);
                 }
                             "Expected %s but got %s on uri_tests[%d].str_props[%d].\n",
                             prop.value, wine_dbgstr_w(received), i, j);
                 }
@@ -7802,9 +7838,11 @@ static void test_IUri_GetStrProperties(void) {
             prop = test.str_props[Uri_PROPERTY_DOMAIN];
             hr = IUri_GetDomain(uri, &received);
             todo_wine_if(prop.todo) {
             prop = test.str_props[Uri_PROPERTY_DOMAIN];
             hr = IUri_GetDomain(uri, &received);
             todo_wine_if(prop.todo) {
-                ok(hr == prop.expected, "Error: GetDomain returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
+                ok(hr == prop.expected || (prop.value2 && hr == prop.expected2),
+                   "Error: GetDomain returned 0x%08x, expected 0x%08x on uri_tests[%d].\n",
                         hr, prop.expected, i);
                         hr, prop.expected, i);
-                ok(!strcmp_aw(prop.value, received), "Error: Expected %s but got %s on uri_tests[%d].\n",
+                ok(!strcmp_aw(prop.value, received) || (prop.value2 && !strcmp_aw(prop.value2, received)),
+                   "Error: Expected %s but got %s on uri_tests[%d].\n",
                         prop.value, wine_dbgstr_w(received), i);
             }
             SysFreeString(received);
                         prop.value, wine_dbgstr_w(received), i);
             }
             SysFreeString(received);
@@ -8082,9 +8120,11 @@ static void test_IUri_GetPropertyLength(void) {
 
                 hr = IUri_GetPropertyLength(uri, j, &receivedLen, 0);
                 todo_wine_if(prop.todo) {
 
                 hr = IUri_GetPropertyLength(uri, j, &receivedLen, 0);
                 todo_wine_if(prop.todo) {
-                    ok(hr == prop.expected, "Error: GetPropertyLength returned 0x%08x, expected 0x%08x on uri_tests[%d].str_props[%d].\n",
+                    ok(hr == prop.expected || (prop.value2 && hr == prop.expected2),
+                       "Error: GetPropertyLength returned 0x%08x, expected 0x%08x on uri_tests[%d].str_props[%d].\n",
                             hr, prop.expected, i, j);
                             hr, prop.expected, i, j);
-                    ok(receivedLen == expectedLen || broken(prop.broken_value && receivedLen == lstrlenA(prop.broken_value)),
+                    ok(receivedLen == expectedLen || (prop.value2 && receivedLen == lstrlenA(prop.value2)) ||
+                       broken(prop.broken_value && receivedLen == lstrlenA(prop.broken_value)),
                             "Error: Expected a length of %d but got %d on uri_tests[%d].str_props[%d].\n",
                             expectedLen, receivedLen, i, j);
                 }
                             "Error: Expected a length of %d but got %d on uri_tests[%d].str_props[%d].\n",
                             expectedLen, receivedLen, i, j);
                 }
@@ -8097,18 +8137,25 @@ static void test_IUri_GetPropertyLength(void) {
     }
 }
 
     }
 }
 
-static DWORD compute_expected_props(uri_properties *test)
+static DWORD compute_expected_props(uri_properties *test, DWORD *mask)
 {
     DWORD ret = 0, i;
 
 {
     DWORD ret = 0, i;
 
+    *mask = 0;
+
     for(i=Uri_PROPERTY_STRING_START; i <= Uri_PROPERTY_STRING_LAST; i++) {
         if(test->str_props[i-Uri_PROPERTY_STRING_START].expected == S_OK)
             ret |= 1<<i;
     for(i=Uri_PROPERTY_STRING_START; i <= Uri_PROPERTY_STRING_LAST; i++) {
         if(test->str_props[i-Uri_PROPERTY_STRING_START].expected == S_OK)
             ret |= 1<<i;
+        if(test->str_props[i-Uri_PROPERTY_STRING_START].value2 == NULL ||
+           test->str_props[i-Uri_PROPERTY_STRING_START].expected ==
+           test->str_props[i-Uri_PROPERTY_STRING_START].expected2)
+            *mask |= 1<<i;
     }
 
     for(i=Uri_PROPERTY_DWORD_START; i <= Uri_PROPERTY_DWORD_LAST; i++) {
         if(test->dword_props[i-Uri_PROPERTY_DWORD_START].expected == S_OK)
             ret |= 1<<i;
     }
 
     for(i=Uri_PROPERTY_DWORD_START; i <= Uri_PROPERTY_DWORD_LAST; i++) {
         if(test->dword_props[i-Uri_PROPERTY_DWORD_START].expected == S_OK)
             ret |= 1<<i;
+        *mask |= 1<<i;
     }
 
     return ret;
     }
 
     return ret;
@@ -8138,20 +8185,22 @@ static void test_IUri_GetProperties(void) {
             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
 
         if(SUCCEEDED(hr)) {
             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
 
         if(SUCCEEDED(hr)) {
-            DWORD received = 0, expected_props;
+            DWORD received = 0, expected_props, mask;
             DWORD j;
 
             hr = IUri_GetProperties(uri, &received);
             ok(hr == S_OK, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
 
             DWORD j;
 
             hr = IUri_GetProperties(uri, &received);
             ok(hr == S_OK, "Error: GetProperties returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
 
-            expected_props = compute_expected_props(&test);
+            expected_props = compute_expected_props(&test, &mask);
 
             for(j = 0; j <= Uri_PROPERTY_DWORD_LAST; ++j) {
                 /* (1 << j) converts a Uri_PROPERTY to its corresponding Uri_HAS_* flag mask. */
 
             for(j = 0; j <= Uri_PROPERTY_DWORD_LAST; ++j) {
                 /* (1 << j) converts a Uri_PROPERTY to its corresponding Uri_HAS_* flag mask. */
-                if(expected_props & (1 << j))
-                    ok(received & (1 << j), "Error: Expected flag for property %d on uri_tests[%d].\n", j, i);
-                else
-                    ok(!(received & (1 << j)), "Error: Received flag for property %d when not expected on uri_tests[%d].\n", j, i);
+                if(mask & (1 << j)) {
+                    if(expected_props & (1 << j))
+                        ok(received & (1 << j), "Error: Expected flag for property %d on uri_tests[%d].\n", j, i);
+                    else
+                        ok(!(received & (1 << j)), "Error: Received flag for property %d when not expected on uri_tests[%d].\n", j, i);
+                }
             }
         }
 
             }
         }
 
@@ -8186,9 +8235,9 @@ static void test_IUri_HasProperty(void) {
             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
 
         if(SUCCEEDED(hr)) {
             ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, test.create_expected);
 
         if(SUCCEEDED(hr)) {
-            DWORD expected_props, j;
+            DWORD expected_props, j, mask;
 
 
-            expected_props = compute_expected_props(&test);
+            expected_props = compute_expected_props(&test, &mask);
 
             for(j = 0; j <= Uri_PROPERTY_DWORD_LAST; ++j) {
                 /* Assign -1, then explicitly test for TRUE or FALSE later. */
 
             for(j = 0; j <= Uri_PROPERTY_DWORD_LAST; ++j) {
                 /* Assign -1, then explicitly test for TRUE or FALSE later. */
@@ -8198,10 +8247,12 @@ static void test_IUri_HasProperty(void) {
                 ok(hr == S_OK, "Error: HasProperty returned 0x%08x, expected 0x%08x for property %d on uri_tests[%d].\n",
                         hr, S_OK, j, i);
 
                 ok(hr == S_OK, "Error: HasProperty returned 0x%08x, expected 0x%08x for property %d on uri_tests[%d].\n",
                         hr, S_OK, j, i);
 
-                if(expected_props & (1 << j)) {
-                    ok(received == TRUE, "Error: Expected to have property %d on uri_tests[%d].\n", j, i);
-                } else {
-                    ok(received == FALSE, "Error: Wasn't expecting to have property %d on uri_tests[%d].\n", j, i);
+                if(mask & (1 << j)) {
+                    if(expected_props & (1 << j)) {
+                        ok(received == TRUE, "Error: Expected to have property %d on uri_tests[%d].\n", j, i);
+                    } else {
+                        ok(received == FALSE, "Error: Wasn't expecting to have property %d on uri_tests[%d].\n", j, i);
+                    }
                 }
             }
         }
                 }
             }
         }
@@ -10410,7 +10461,9 @@ static void test_CoInternetParseIUri_InvalidArgs(void) {
     HRESULT hr;
     IUri *uri = NULL;
     WCHAR tmp[3];
     HRESULT hr;
     IUri *uri = NULL;
     WCHAR tmp[3];
+    WCHAR *longurl, *copy;
     DWORD result = -1;
     DWORD result = -1;
+    DWORD i, len;
 
     hr = pCoInternetParseIUri(NULL, PARSE_CANONICALIZE, 0, tmp, 3, &result, 0);
     ok(hr == E_INVALIDARG, "Error: CoInternetParseIUri returned 0x%08x, expected 0x%08x.\n",
 
     hr = pCoInternetParseIUri(NULL, PARSE_CANONICALIZE, 0, tmp, 3, &result, 0);
     ok(hr == E_INVALIDARG, "Error: CoInternetParseIUri returned 0x%08x, expected 0x%08x.\n",
@@ -10466,6 +10519,33 @@ static void test_CoInternetParseIUri_InvalidArgs(void) {
             expected_len, result);
     }
     if(uri) IUri_Release(uri);
             expected_len, result);
     }
     if(uri) IUri_Release(uri);
+
+    /* a long url that causes a crash on Wine */
+    len = INTERNET_MAX_URL_LENGTH*2;
+    longurl = heap_alloc((len+1)*sizeof(WCHAR));
+    memcpy(longurl, http_urlW, sizeof(http_urlW));
+    for(i = sizeof(http_urlW)/sizeof(WCHAR)-1; i < len; i++)
+        longurl[i] = 'x';
+    longurl[len] = 0;
+
+    copy = heap_alloc((len+1)*sizeof(WCHAR));
+    memcpy(copy, longurl, (len+1)*sizeof(WCHAR));
+
+    hr = pCreateUri(longurl, 0, 0, &uri);
+    ok(SUCCEEDED(hr), "Error: CreateUri returned 0x%08x.\n", hr);
+    if(SUCCEEDED(hr)) {
+        result = -1;
+        memset(longurl, 0xcc, len*sizeof(WCHAR));
+        hr = pCoInternetParseIUri(uri, PARSE_CANONICALIZE, 0, longurl, len+1, &result, 0);
+        ok(SUCCEEDED(hr), "Error: CoInternetParseIUri returned 0x%08x.\n", hr);
+        ok(!lstrcmpW(longurl, copy), "Error: expected long url '%s' but was '%s'.\n",
+            wine_dbgstr_w(copy), wine_dbgstr_w(longurl));
+        ok(result == len, "Error: Expected 'result' to be %d, but was %d instead.\n",
+            len, result);
+    }
+    heap_free(longurl);
+    heap_free(copy);
+    if(uri) IUri_Release(uri);
 }
 
 static void test_CoInternetParseIUri(void) {
 }
 
 static void test_CoInternetParseIUri(void) {
@@ -10491,10 +10571,10 @@ static void test_CoInternetParseIUri(void) {
                     hr, test.expected, i);
             if(SUCCEEDED(hr)) {
                 DWORD len = lstrlenA(test.property);
                     hr, test.expected, i);
             if(SUCCEEDED(hr)) {
                 DWORD len = lstrlenA(test.property);
-                ok(!strcmp_aw(test.property, result),
+                ok(!strcmp_aw(test.property, result) || (test.property2 && !strcmp_aw(test.property2, result)),
                     "Error: Expected %s but got %s instead on uri_parse_tests[%d].\n",
                     test.property, wine_dbgstr_w(result), i);
                     "Error: Expected %s but got %s instead on uri_parse_tests[%d].\n",
                     test.property, wine_dbgstr_w(result), i);
-                ok(len == result_len,
+                ok(len == result_len || (test.property2 && lstrlenA(test.property2) == result_len),
                     "Error: Expected %d, but got %d instead on uri_parse_tests[%d].\n",
                     len, result_len, i);
             } else {
                     "Error: Expected %d, but got %d instead on uri_parse_tests[%d].\n",
                     len, result_len, i);
             } else {
index d9a3811..1cc8863 100644 (file)
@@ -1957,6 +1957,31 @@ static HRESULT WINAPI statusclb_GetBindInfo(IBindStatusCallbackEx *iface, DWORD
     return S_OK;
 }
 
     return S_OK;
 }
 
+static void test_stream_seek(IStream *stream)
+{
+    ULARGE_INTEGER new_pos;
+    LARGE_INTEGER pos;
+    HRESULT hres;
+
+    pos.QuadPart = 0;
+    new_pos.QuadPart = 0xdeadbeef;
+    hres = IStream_Seek(stream, pos, STREAM_SEEK_SET, &new_pos);
+    ok(hres == S_OK, "Seek failed: %08x\n", hres);
+    ok(!new_pos.QuadPart, "new_pos.QuadPart != 0\n");
+
+    pos.QuadPart = 0;
+    new_pos.QuadPart = 0xdeadbeef;
+    hres = IStream_Seek(stream, pos, STREAM_SEEK_END, &new_pos);
+    ok(hres == S_OK, "Seek failed: %08x\n", hres);
+    ok(new_pos.QuadPart, "new_pos.QuadPart = 0\n");
+
+    pos.QuadPart = 0;
+    new_pos.QuadPart = 0xdeadbeef;
+    hres = IStream_Seek(stream, pos, 100, &new_pos);
+    ok(hres == E_FAIL, "Seek failed: %08x\n", hres);
+    ok(new_pos.QuadPart == 0xdeadbeef, "unexpected new_pos.QuadPart\n");
+}
+
 static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DWORD grfBSCF,
         DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
 {
 static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DWORD grfBSCF,
         DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
 {
@@ -2003,24 +2028,28 @@ static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DW
     ok(pstgmed->pUnkForRelease != NULL, "pUnkForRelease == NULL\n");
 
     switch(pstgmed->tymed) {
     ok(pstgmed->pUnkForRelease != NULL, "pUnkForRelease == NULL\n");
 
     switch(pstgmed->tymed) {
-    case TYMED_ISTREAM:
+    case TYMED_ISTREAM: {
+        IStream *stream = U(*pstgmed).pstm;
+
+        ok(stream != NULL, "U(*pstgmed).pstm == NULL\n");
+
         if(grfBSCF & BSCF_FIRSTDATANOTIFICATION) {
             STATSTG stat;
 
         if(grfBSCF & BSCF_FIRSTDATANOTIFICATION) {
             STATSTG stat;
 
-            hres = IStream_Write(U(*pstgmed).pstm, buf, 10, NULL);
+            hres = IStream_Write(stream, buf, 10, NULL);
             ok(hres == STG_E_ACCESSDENIED,
                "Write failed: %08x, expected STG_E_ACCESSDENIED\n", hres);
 
             ok(hres == STG_E_ACCESSDENIED,
                "Write failed: %08x, expected STG_E_ACCESSDENIED\n", hres);
 
-            hres = IStream_Commit(U(*pstgmed).pstm, 0);
+            hres = IStream_Commit(stream, 0);
             ok(hres == E_NOTIMPL, "Commit failed: %08x, expected E_NOTIMPL\n", hres);
 
             ok(hres == E_NOTIMPL, "Commit failed: %08x, expected E_NOTIMPL\n", hres);
 
-            hres = IStream_Revert(U(*pstgmed).pstm);
+            hres = IStream_Revert(stream);
             ok(hres == E_NOTIMPL, "Revert failed: %08x, expected E_NOTIMPL\n", hres);
 
             ok(hres == E_NOTIMPL, "Revert failed: %08x, expected E_NOTIMPL\n", hres);
 
-            hres = IStream_Stat(U(*pstgmed).pstm, NULL, STATFLAG_NONAME);
+            hres = IStream_Stat(stream, NULL, STATFLAG_NONAME);
             ok(hres == E_FAIL, "hres = %x\n", hres);
             if(use_cache_file && emulate_protocol) {
             ok(hres == E_FAIL, "hres = %x\n", hres);
             if(use_cache_file && emulate_protocol) {
-                hres = IStream_Stat(U(*pstgmed).pstm, &stat, STATFLAG_DEFAULT);
+                hres = IStream_Stat(stream, &stat, STATFLAG_DEFAULT);
                 ok(hres == S_OK, "hres = %x\n", hres);
                 ok(!lstrcmpW(stat.pwcsName, cache_file_name),
                         "stat.pwcsName = %s, cache_file_name = %s\n",
                 ok(hres == S_OK, "hres = %x\n", hres);
                 ok(!lstrcmpW(stat.pwcsName, cache_file_name),
                         "stat.pwcsName = %s, cache_file_name = %s\n",
@@ -2029,7 +2058,7 @@ static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DW
                 ok(U(stat.cbSize).LowPart == (bindf&BINDF_ASYNCHRONOUS?0:6500),
                         "stat.cbSize.LowPart = %u\n", U(stat.cbSize).LowPart);
             } else {
                 ok(U(stat.cbSize).LowPart == (bindf&BINDF_ASYNCHRONOUS?0:6500),
                         "stat.cbSize.LowPart = %u\n", U(stat.cbSize).LowPart);
             } else {
-                hres = IStream_Stat(U(*pstgmed).pstm, &stat, STATFLAG_NONAME);
+                hres = IStream_Stat(stream, &stat, STATFLAG_NONAME);
                 ok(hres == S_OK, "hres = %x\n", hres);
                 ok(!stat.pwcsName || broken(stat.pwcsName!=NULL),
                         "stat.pwcsName = %s\n", wine_dbgstr_w(stat.pwcsName));
                 ok(hres == S_OK, "hres = %x\n", hres);
                 ok(!stat.pwcsName || broken(stat.pwcsName!=NULL),
                         "stat.pwcsName = %s\n", wine_dbgstr_w(stat.pwcsName));
@@ -2042,17 +2071,19 @@ static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DW
             ok(stat.reserved == 0, "stat.reserved = %x\n", stat.reserved);
         }
 
             ok(stat.reserved == 0, "stat.reserved = %x\n", stat.reserved);
         }
 
-        ok(U(*pstgmed).pstm != NULL, "U(*pstgmed).pstm == NULL\n");
         if(callback_read) {
             do {
         if(callback_read) {
             do {
-                hres = IStream_Read(U(*pstgmed).pstm, buf, 512, &readed);
+                hres = IStream_Read(stream, buf, 512, &readed);
                 if(test_protocol == HTTP_TEST && emulate_protocol && readed)
                     ok(buf[0] == (use_cache_file && !(bindf&BINDF_ASYNCHRONOUS) ? 'X' : '?'), "buf[0] = '%c'\n", buf[0]);
             }while(hres == S_OK);
             ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08x\n", hres);
         }
                 if(test_protocol == HTTP_TEST && emulate_protocol && readed)
                     ok(buf[0] == (use_cache_file && !(bindf&BINDF_ASYNCHRONOUS) ? 'X' : '?'), "buf[0] = '%c'\n", buf[0]);
             }while(hres == S_OK);
             ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08x\n", hres);
         }
-        break;
 
 
+        if(use_cache_file && (grfBSCF & BSCF_FIRSTDATANOTIFICATION) && !(bindf & BINDF_PULLDATA))
+            test_stream_seek(stream);
+        break;
+    }
     case TYMED_FILE:
         if(test_protocol == FILE_TEST)
             ok(!lstrcmpW(pstgmed->u.lpszFileName, file_url+7),
     case TYMED_FILE:
         if(test_protocol == FILE_TEST)
             ok(!lstrcmpW(pstgmed->u.lpszFileName, file_url+7),