[URLMON_WINETEST]
[reactos.git] / rostests / winetests / urlmon / misc.c
index ba36d8a..2e77c1b 100644 (file)
@@ -18,6 +18,7 @@
 
 #define COBJMACROS
 #define CONST_VTABLE
+#define NONAMELESSUNION
 
 #include <wine/test.h>
 #include <stdarg.h>
@@ -62,13 +63,6 @@ DEFINE_EXPECT(QI_IInternetProtocolInfo);
 DEFINE_EXPECT(CreateInstance);
 DEFINE_EXPECT(unk_Release);
 
-static const char *debugstr_w(LPCWSTR str)
-{
-    static char buf[1024];
-    WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
-    return buf;
-}
-
 static void test_CreateFormatEnum(void)
 {
     IEnumFORMATETC *fenum = NULL, *fenum2 = NULL;
@@ -249,7 +243,7 @@ static void test_RegisterFormatEnumerator(void)
 static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',
         '/','b','l','a','n','k','.','h','t','m',0};
 static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
-static const WCHAR url3[] = {'f','i','l','e',':','c',':','\\','I','n','d','e','x','.','h','t','m',0};
+static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0};
 static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
         '%','2','e','j','p','g',0};
 static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
@@ -258,7 +252,11 @@ static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
 static const WCHAR url7[] = {'f','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',
         'f','i','l','e','.','t','e','s','t',0};
 static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
-
+static const WCHAR url9[] =
+    {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
+     '/','s','i','t','e','/','a','b','o','u','t',0};
+static const WCHAR url10[] = {'f','i','l','e',':','/','/','s','o','m','e','%','2','0','f','i','l','e',
+        '.','j','p','g',0};
 
 static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
         '.','j','p','g',0};
@@ -272,6 +270,10 @@ static const WCHAR wszHttp[] = {'h','t','t','p',0};
 static const WCHAR wszAbout[] = {'a','b','o','u','t',0};
 static const WCHAR wszEmpty[] = {0};
 
+static const WCHAR wszWineHQ[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
+static const WCHAR wszHttpWineHQ[] = {'h','t','t','p',':','/','/','w','w','w','.',
+    'w','i','n','e','h','q','.','o','r','g',0};
+
 struct parse_test {
     LPCWSTR url;
     HRESULT secur_hres;
@@ -279,15 +281,19 @@ struct parse_test {
     HRESULT path_hres;
     LPCWSTR path;
     LPCWSTR schema;
+    LPCWSTR domain;
+    HRESULT domain_hres;
+    LPCWSTR rootdocument;
+    HRESULT rootdocument_hres;
 };
 
 static const struct parse_test parse_tests[] = {
-    {url1, S_OK,   url1,  E_INVALIDARG, NULL, wszRes},
-    {url2, E_FAIL, url2,  E_INVALIDARG, NULL, wszEmpty},
-    {url3, E_FAIL, url3,  S_OK, path3,        wszFile},
-    {url4, E_FAIL, url4e, S_OK, path4,        wszFile},
-    {url5, E_FAIL, url5,  E_INVALIDARG, NULL, wszHttp},
-    {url6, S_OK,   url6,  E_INVALIDARG, NULL, wszAbout}
+    {url1, S_OK,   url1,  E_INVALIDARG, NULL, wszRes, NULL, E_FAIL, NULL, E_FAIL},
+    {url2, E_FAIL, url2,  E_INVALIDARG, NULL, wszEmpty, NULL, E_FAIL, NULL, E_FAIL},
+    {url3, E_FAIL, url3,  S_OK, path3,        wszFile, wszEmpty, S_OK, NULL, E_FAIL},
+    {url4, E_FAIL, url4e, S_OK, path4,        wszFile, wszEmpty, S_OK, NULL, E_FAIL},
+    {url5, E_FAIL, url5,  E_INVALIDARG, NULL, wszHttp, wszWineHQ, S_OK, wszHttpWineHQ, S_OK},
+    {url6, S_OK,   url6,  E_INVALIDARG, NULL, wszAbout, NULL, E_FAIL, NULL, E_FAIL},
 };
 
 static void test_CoInternetParseUrl(void)
@@ -333,6 +339,23 @@ static void test_CoInternetParseUrl(void)
         ok(hres == S_OK, "[%d] schema failed: %08x\n", i, hres);
         ok(size == lstrlenW(parse_tests[i].schema), "[%d] wrong size\n", i);
         ok(!lstrcmpW(parse_tests[i].schema, buf), "[%d] wrong schema\n", i);
+
+        if(memcmp(parse_tests[i].url, wszRes, 3*sizeof(WCHAR))
+                && memcmp(parse_tests[i].url, wszAbout, 5*sizeof(WCHAR))) {
+            memset(buf, 0xf0, sizeof(buf));
+            hres = CoInternetParseUrl(parse_tests[i].url, PARSE_DOMAIN, 0, buf,
+                    sizeof(buf)/sizeof(WCHAR), &size, 0);
+            ok(hres == parse_tests[i].domain_hres, "[%d] domain failed: %08x\n", i, hres);
+            if(parse_tests[i].domain)
+                ok(!lstrcmpW(parse_tests[i].domain, buf), "[%d] wrong domain, received %s\n", i, wine_dbgstr_w(buf));
+        }
+
+        memset(buf, 0xf0, sizeof(buf));
+        hres = CoInternetParseUrl(parse_tests[i].url, PARSE_ROOTDOCUMENT, 0, buf,
+                sizeof(buf)/sizeof(WCHAR), &size, 0);
+        ok(hres == parse_tests[i].rootdocument_hres, "[%d] rootdocument failed: %08x\n", i, hres);
+        if(parse_tests[i].rootdocument)
+            ok(!lstrcmpW(parse_tests[i].rootdocument, buf), "[%d] wrong rootdocument, received %s\n", i, wine_dbgstr_w(buf));
     }
 }
 
@@ -417,6 +440,7 @@ static const WCHAR mimeAppPdf[] = {'a','p','p','l','i','c','a','t','i','o','n','
 static const WCHAR mimeAppXMSDownload[] =
     {'a','p','p','l','i','c','a','t','i','o','n','/','x','-','m','s','d','o','w','n','l','o','a','d',0};
 static const WCHAR mimeAudioWav[] = {'a','u','d','i','o','/','w','a','v',0};
+static const WCHAR mimeAudioBasic[] = {'a','u','d','i','o','/','b','a','s','i','c',0};
 
 static const struct {
     LPCWSTR url;
@@ -513,11 +537,15 @@ static BYTE data78[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'<','h','t','m','l',
 static BYTE data79[] = {'%','!',0xff};
 static BYTE data80[] = {'%','!'};
 static BYTE data81[] = {'%','!','P','S','<','h','t','m','l','>'};
+static BYTE data82[] = {'.','s','n','d',0};
+static BYTE data83[] = {'.','s','n','d'};
+static BYTE data84[] = {'.','s','n','d',0,'<','h','t','m','l','>',1,1};
+static BYTE data85[] = {'.','S','N','D',0};
 
 static const struct {
     BYTE *data;
     DWORD size;
-    LPCWSTR mime;
+    LPCWSTR mime, mime_alt;
 } mime_tests2[] = {
     {data1, sizeof(data1), mimeTextPlain},
     {data2, sizeof(data2), mimeAppOctetStream},
@@ -525,12 +553,12 @@ static const struct {
     {data4, sizeof(data4), mimeAppOctetStream},
     {data5, sizeof(data5), mimeTextPlain},
     {data6, sizeof(data6), mimeTextPlain},
-    {data7, sizeof(data7), mimeTextHtml},
-    {data8, sizeof(data8), mimeTextHtml},
-    {data9, sizeof(data9), mimeTextHtml},
-    {data10, sizeof(data10), mimeTextHtml},
-    {data11, sizeof(data11), mimeTextHtml},
-    {data12, sizeof(data12), mimeTextHtml},
+    {data7, sizeof(data7), mimeTextHtml, mimeTextPlain /* IE8 */},
+    {data8, sizeof(data8), mimeTextHtml, mimeTextPlain /* IE8 */},
+    {data9, sizeof(data9), mimeTextHtml, mimeImagePjpeg /* IE8 */},
+    {data10, sizeof(data10), mimeTextHtml, mimeTextPlain /* IE8 */},
+    {data11, sizeof(data11), mimeTextHtml, mimeTextPlain /* IE8 */},
+    {data12, sizeof(data12), mimeTextHtml, mimeTextPlain /* IE8 */},
     {data13, sizeof(data13), mimeTextPlain},
     {data14, sizeof(data14), mimeTextPlain},
     {data15, sizeof(data15), mimeTextPlain},
@@ -544,21 +572,21 @@ static const struct {
     {data23, sizeof(data23), mimeTextPlain},
     {data24, sizeof(data24), mimeImageGif},
     {data25, sizeof(data25), mimeImageGif},
-    {data26, sizeof(data26), mimeTextHtml},
+    {data26, sizeof(data26), mimeTextHtml, mimeImageGif /* IE8 */},
     {data27, sizeof(data27), mimeTextPlain},
     {data28, sizeof(data28), mimeImageBmp},
     {data29, sizeof(data29), mimeImageBmp},
     {data30, sizeof(data30), mimeAppOctetStream},
-    {data31, sizeof(data31), mimeTextHtml},
+    {data31, sizeof(data31), mimeTextHtml, mimeImageBmp /* IE8 */},
     {data32, sizeof(data32), mimeAppOctetStream},
     {data33, sizeof(data33), mimeAppOctetStream},
     {data34, sizeof(data34), mimeImageXPng},
     {data35, sizeof(data35), mimeImageXPng},
     {data36, sizeof(data36), mimeAppOctetStream},
-    {data37, sizeof(data37), mimeTextHtml},
+    {data37, sizeof(data37), mimeTextHtml, mimeImageXPng /* IE8 */},
     {data38, sizeof(data38), mimeAppOctetStream},
     {data39, sizeof(data39), mimeImageTiff},
-    {data40, sizeof(data40), mimeTextHtml},
+    {data40, sizeof(data40), mimeTextHtml, mimeImageTiff /* IE8 */},
     {data41, sizeof(data41), mimeImageTiff},
     {data42, sizeof(data42), mimeTextPlain},
     {data43, sizeof(data43), mimeAppOctetStream},
@@ -566,40 +594,44 @@ static const struct {
     {data45, sizeof(data45), mimeTextPlain},
     {data46, sizeof(data46), mimeTextPlain},
     {data47, sizeof(data47), mimeTextPlain},
-    {data48, sizeof(data48), mimeTextHtml},
+    {data48, sizeof(data48), mimeTextHtml, mimeVideoAvi /* IE8 */},
     {data49, sizeof(data49), mimeVideoAvi},
     {data50, sizeof(data50), mimeVideoMpeg},
     {data51, sizeof(data51), mimeVideoMpeg},
     {data52, sizeof(data52), mimeAppOctetStream},
     {data53, sizeof(data53), mimeAppOctetStream},
-    {data54, sizeof(data54), mimeTextHtml},
+    {data54, sizeof(data54), mimeTextHtml, mimeVideoMpeg /* IE8 */},
     {data55, sizeof(data55), mimeAppXGzip},
     {data56, sizeof(data56), mimeTextPlain},
-    {data57, sizeof(data57), mimeTextHtml},
+    {data57, sizeof(data57), mimeTextHtml, mimeAppXGzip /* IE8 */},
     {data58, sizeof(data58), mimeAppOctetStream},
     {data59, sizeof(data59), mimeAppXZip},
     {data60, sizeof(data60), mimeTextPlain},
-    {data61, sizeof(data61), mimeTextHtml},
+    {data61, sizeof(data61), mimeTextHtml, mimeAppXZip /* IE8 */},
     {data62, sizeof(data62), mimeAppJava},
     {data63, sizeof(data63), mimeTextPlain},
-    {data64, sizeof(data64), mimeTextHtml},
+    {data64, sizeof(data64), mimeTextHtml, mimeAppJava /* IE8 */},
     {data65, sizeof(data65), mimeAppPdf},
     {data66, sizeof(data66), mimeTextPlain},
-    {data67, sizeof(data67), mimeTextHtml},
+    {data67, sizeof(data67), mimeTextHtml, mimeAppPdf /* IE8 */},
     {data68, sizeof(data68), mimeAppXMSDownload},
     {data69, sizeof(data69), mimeTextPlain},
-    {data70, sizeof(data70), mimeTextHtml},
+    {data70, sizeof(data70), mimeTextHtml, mimeAppXMSDownload /* IE8 */},
     {data71, sizeof(data71), mimeTextRichtext},
     {data72, sizeof(data72), mimeTextPlain},
     {data73, sizeof(data73), mimeTextPlain},
-    {data74, sizeof(data74), mimeTextHtml},
+    {data74, sizeof(data74), mimeTextHtml, mimeTextRichtext /* IE8 */},
     {data75, sizeof(data75), mimeAudioWav},
     {data76, sizeof(data76), mimeTextPlain},
     {data77, sizeof(data77), mimeTextPlain},
-    {data78, sizeof(data78), mimeTextHtml},
+    {data78, sizeof(data78), mimeTextHtml, mimeTextPlain /* IE8 */},
     {data79, sizeof(data79), mimeAppPostscript},
     {data80, sizeof(data80), mimeTextPlain},
-    {data81, sizeof(data81), mimeTextHtml}
+    {data81, sizeof(data81), mimeTextHtml, mimeAppPostscript /* IE8 */},
+    {data82, sizeof(data82), mimeAudioBasic},
+    {data83, sizeof(data83), mimeTextPlain},
+    {data84, sizeof(data84), mimeTextHtml, mimeAudioBasic /* IE8 */},
+    {data85, sizeof(data85), mimeTextPlain}
 };
 
 static void test_FindMimeFromData(void)
@@ -639,7 +671,7 @@ static void test_FindMimeFromData(void)
         hres = FindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
                 NULL, 0, &mime, 0);
         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
-        ok(!lstrcmpW(mime, mime_tests2[i].mime), "[%d] wrong mime: %s\n", i, debugstr_w(mime));
+        ok(!lstrcmpW(mime, mime_tests2[i].mime), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
         CoTaskMemFree(mime);
 
         hres = FindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
@@ -658,7 +690,9 @@ static void test_FindMimeFromData(void)
         if(!lstrcmpW(mimeAppOctetStream, mime_tests2[i].mime) || i == 17)
             ok(!lstrcmpW(mime, mimeImagePjpeg), "[%d] wrong mime\n", i);
         else
-            ok(!lstrcmpW(mime, mime_tests2[i].mime), "[%d] wrong mime\n", i);
+            ok(!lstrcmpW(mime, mime_tests2[i].mime) ||
+                    (mime_tests2[i].mime_alt && !lstrcmpW(mime, mime_tests2[i].mime_alt)),
+                    "[%d] wrong mime, got %s\n", i, wine_dbgstr_w(mime));
 
         CoTaskMemFree(mime);
     }
@@ -699,127 +733,6 @@ static void test_FindMimeFromData(void)
     ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
 }
 
-static const BYTE secid1[] = {'f','i','l','e',':',0,0,0,0};
-static const BYTE secid4[] ={'f','i','l','e',':',3,0,0,0};
-static const BYTE secid5[] = {'h','t','t','p',':','w','w','w','.','w','i','n','e','h','q',
-    '.','o','r','g',3,0,0,0};
-static const BYTE secid6[] = {'a','b','o','u','t',':','b','l','a','n','k',3,0,0,0};
-static const BYTE secid7[] = {'f','t','p',':','w','i','n','e','h','q','.','o','r','g',
-                              3,0,0,0};
-
-static struct secmgr_test {
-    LPCWSTR url;
-    DWORD zone;
-    HRESULT zone_hres;
-    DWORD secid_size;
-    const BYTE *secid;
-    HRESULT secid_hres;
-} secmgr_tests[] = {
-    {url1, 0,   S_OK, sizeof(secid1), secid1, S_OK},
-    {url2, 100, 0x80041001, 0, NULL, E_INVALIDARG},
-    {url3, 0,   S_OK, sizeof(secid1), secid1, S_OK},
-    {url4, 3,   S_OK, sizeof(secid4), secid4, S_OK},
-    {url5, 3,   S_OK, sizeof(secid5), secid5, S_OK},
-    {url6, 3,   S_OK, sizeof(secid6), secid6, S_OK},
-    {url7, 3,   S_OK, sizeof(secid7), secid7, S_OK}
-};
-
-static void test_SecurityManager(void)
-{
-    int i;
-    IInternetSecurityManager *secmgr = NULL;
-    BYTE buf[512];
-    DWORD zone, size;
-    HRESULT hres;
-
-    hres = CoInternetCreateSecurityManager(NULL, &secmgr, 0);
-    ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres);
-    if(FAILED(hres))
-        return;
-
-    for(i=0; i < sizeof(secmgr_tests)/sizeof(secmgr_tests[0]); i++) {
-        zone = 100;
-        hres = IInternetSecurityManager_MapUrlToZone(secmgr, secmgr_tests[i].url,
-                                                     &zone, 0);
-        ok(hres == secmgr_tests[i].zone_hres,
-           "[%d] MapUrlToZone failed: %08x, expected %08x\n",
-                i, hres, secmgr_tests[i].zone_hres);
-        if(SUCCEEDED(hres))
-            ok(zone == secmgr_tests[i].zone, "[%d] zone=%d, expected %d\n", i, zone,
-               secmgr_tests[i].zone);
-        else
-            ok(zone == secmgr_tests[i].zone || zone == -1, "[%d] zone=%d\n", i, zone);
-
-        size = sizeof(buf);
-        memset(buf, 0xf0, sizeof(buf));
-        hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[i].url,
-                buf, &size, 0);
-        ok(hres == secmgr_tests[i].secid_hres,
-           "[%d] GetSecurityId failed: %08x, expected %08x\n",
-           i, hres, secmgr_tests[i].secid_hres);
-        if(secmgr_tests[i].secid) {
-            ok(size == secmgr_tests[i].secid_size, "[%d] size=%d, expected %d\n",
-                    i, size, secmgr_tests[i].secid_size);
-            ok(!memcmp(buf, secmgr_tests[i].secid, size), "[%d] wrong secid\n", i);
-        }
-    }
-
-    zone = 100;
-    hres = IInternetSecurityManager_MapUrlToZone(secmgr, NULL, &zone, 0);
-    ok(hres == E_INVALIDARG, "MapUrlToZone failed: %08x, expected E_INVALIDARG\n", hres);
-    ok(zone == 100 || zone == -1, "zone=%d\n", zone);
-
-    size = sizeof(buf);
-    hres = IInternetSecurityManager_GetSecurityId(secmgr, NULL, buf, &size, 0);
-    ok(hres == E_INVALIDARG,
-       "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
-    hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[1].url,
-                                                  NULL, &size, 0);
-    ok(hres == E_INVALIDARG,
-       "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
-    hres = IInternetSecurityManager_GetSecurityId(secmgr, secmgr_tests[1].url,
-                                                  buf, NULL, 0);
-    ok(hres == E_INVALIDARG,
-       "GetSecurityId failed: %08x, expected E_INVALIDARG\n", hres);
-
-    IInternetSecurityManager_Release(secmgr);
-}
-
-static void test_ZoneManager(void)
-{
-    IInternetZoneManager *zonemgr = NULL;
-    BYTE buf[32];
-    HRESULT hres;
-
-    hres = CoInternetCreateZoneManager(NULL, &zonemgr, 0);
-    ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres);
-    if(FAILED(hres))
-        return;
-
-    hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1a10, buf,
-            sizeof(DWORD), URLZONEREG_DEFAULT);
-    ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres);
-    ok(*(DWORD*)buf == 1, "policy=%d, expected 1\n", *(DWORD*)buf);
-
-    hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1a10, NULL,
-            sizeof(DWORD), URLZONEREG_DEFAULT);
-    ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
-
-    hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1a10, buf,
-            2, URLZONEREG_DEFAULT);
-    ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
-
-    hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1fff, buf,
-            sizeof(DWORD), URLZONEREG_DEFAULT);
-    ok(hres == E_FAIL, "GetZoneActionPolicy failed: %08x, expected E_FAIL\n", hres);
-
-    hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 13, 0x1a10, buf,
-            sizeof(DWORD), URLZONEREG_DEFAULT);
-    ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres);
-
-    IInternetZoneManager_Release(zonemgr);
-}
-
 static void register_protocols(void)
 {
     IInternetSession *session;
@@ -867,7 +780,19 @@ static HRESULT WINAPI InternetProtocolInfo_ParseUrl(IInternetProtocolInfo *iface
         PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
         DWORD *pcchResult, DWORD dwReserved)
 {
-    CHECK_EXPECT(ParseUrl);
+    CHECK_EXPECT2(ParseUrl);
+
+    if(ParseAction == PARSE_SECURITY_URL) {
+        if(pcchResult)
+            *pcchResult = sizeof(url1)/sizeof(WCHAR);
+
+        if(cchResult<sizeof(url1)/sizeof(WCHAR))
+            return S_FALSE;
+
+        memcpy(pwzResult, url1, sizeof(url1));
+        return S_OK;
+    }
+
     return E_NOTIMPL;
 }
 
@@ -912,7 +837,7 @@ static IClassFactory *expect_cf;
 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
 {
     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
-        CHECK_EXPECT(QI_IInternetProtocolInfo);
+        CHECK_EXPECT2(QI_IInternetProtocolInfo);
         ok(iface == expect_cf, "unexpected iface\n");
         *ppv = &protocol_info;
         return qiret;
@@ -983,6 +908,7 @@ static void test_NameSpace(void)
 {
     IInternetSession *session;
     WCHAR buf[200];
+    LPWSTR sec_url;
     DWORD size;
     HRESULT hres;
 
@@ -1030,6 +956,34 @@ static void test_NameSpace(void)
     CHECK_CALLED(QI_IInternetProtocolInfo);
     CHECK_CALLED(ParseUrl);
 
+    SET_EXPECT(QI_IInternetProtocolInfo);
+    SET_EXPECT(ParseUrl);
+
+    hres = CoInternetParseUrl(url8, PARSE_SECURITY_URL, 0, buf,
+            sizeof(buf)/sizeof(WCHAR), &size, 0);
+    ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
+    ok(size == sizeof(url1)/sizeof(WCHAR), "Size = %d\n", size);
+    if(size == sizeof(url1)/sizeof(WCHAR))
+        ok(!memcmp(buf, url1, sizeof(url1)), "Encoded url = %s\n", wine_dbgstr_w(buf));
+
+    CHECK_CALLED(QI_IInternetProtocolInfo);
+    CHECK_CALLED(ParseUrl);
+
+    SET_EXPECT(QI_IInternetProtocolInfo);
+    SET_EXPECT(ParseUrl);
+
+    hres = CoInternetGetSecurityUrl(url8, &sec_url, PSU_SECURITY_URL_ONLY, 0);
+    ok(hres == S_OK, "CoInternetGetSecurityUrl failed: %08x\n", hres);
+    if(hres == S_OK) {
+        ok(lstrlenW(sec_url)>sizeof(wszFile)/sizeof(WCHAR) &&
+                !memcmp(sec_url, wszFile, sizeof(wszFile)-sizeof(WCHAR)),
+                "Encoded url = %s\n", wine_dbgstr_w(sec_url));
+        CoTaskMemFree(sec_url);
+    }
+
+    CHECK_CALLED(QI_IInternetProtocolInfo);
+    CHECK_CALLED(ParseUrl);
+
     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
 
@@ -1174,6 +1128,52 @@ static void test_ReleaseBindInfo(void)
     ok(bi.pUnk == &unk, "bi.pUnk=%p, expected %p\n", bi.pUnk, &unk);
 }
 
+static void test_CopyStgMedium(void)
+{
+    STGMEDIUM src, dst;
+    HGLOBAL empty;
+    HRESULT hres;
+
+    static WCHAR fileW[] = {'f','i','l','e',0};
+
+    memset(&src, 0xf0, sizeof(src));
+    memset(&dst, 0xe0, sizeof(dst));
+    memset(&empty, 0xf0, sizeof(empty));
+    src.tymed = TYMED_NULL;
+    src.pUnkForRelease = NULL;
+    hres = CopyStgMedium(&src, &dst);
+    ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
+    ok(dst.tymed == TYMED_NULL, "tymed=%d\n", dst.tymed);
+    ok(dst.u.hGlobal == empty, "u=%p\n", dst.u.hGlobal);
+    ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
+
+    memset(&dst, 0xe0, sizeof(dst));
+    src.tymed = TYMED_ISTREAM;
+    src.u.pstm = NULL;
+    src.pUnkForRelease = NULL;
+    hres = CopyStgMedium(&src, &dst);
+    ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
+    ok(dst.tymed == TYMED_ISTREAM, "tymed=%d\n", dst.tymed);
+    ok(!dst.u.pstm, "pstm=%p\n", dst.u.pstm);
+    ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
+
+    memset(&dst, 0xe0, sizeof(dst));
+    src.tymed = TYMED_FILE;
+    src.u.lpszFileName = fileW;
+    src.pUnkForRelease = NULL;
+    hres = CopyStgMedium(&src, &dst);
+    ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
+    ok(dst.tymed == TYMED_FILE, "tymed=%d\n", dst.tymed);
+    ok(dst.u.lpszFileName && dst.u.lpszFileName != fileW, "lpszFileName=%p\n", dst.u.lpszFileName);
+    ok(!lstrcmpW(dst.u.lpszFileName, fileW), "wrong file name\n");
+    ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
+
+    hres = CopyStgMedium(&src, NULL);
+    ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
+    hres = CopyStgMedium(NULL, &dst);
+    ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
+}
+
 static void test_UrlMkGetSessionOption(void)
 {
     DWORD encoding, size;
@@ -1214,9 +1214,11 @@ static void test_UrlMkGetSessionOption(void)
     ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
 }
 
-static void test_ObtainUserAgentString(void)
+static void test_user_agent(void)
 {
     static const CHAR expected[] = "Mozilla/4.0 (compatible; MSIE ";
+    static char test_str[] = "test";
+    static char test2_str[] = "test\0test";
     static CHAR str[3];
     LPSTR str2 = NULL;
     HRESULT hres;
@@ -1248,29 +1250,156 @@ static void test_ObtainUserAgentString(void)
     ok(size > 0, "size=%d, expected non-zero\n", size);
 
     str2 = HeapAlloc(GetProcessHeap(), 0, (size+20)*sizeof(CHAR));
-    if (!str2)
-    {
-        skip("skipping rest of ObtainUserAgent tests, out of memory\n");
-    }
-    else
-    {
-        saved = size;
-        hres = ObtainUserAgentString(0, str2, &size);
-        ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
-        ok(size == saved, "size=%d, expected %d\n", size, saved);
-        ok(strlen(expected) <= strlen(str2) &&
-           !memcmp(expected, str2, strlen(expected)*sizeof(CHAR)),
-           "user agent was \"%s\", expected to start with \"%s\"\n",
-           str2, expected);
-
-        size = saved+10;
-        hres = ObtainUserAgentString(0, str2, &size);
-        ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
-        ok(size == saved, "size=%d, expected %d\n", size, saved);
-    }
+    saved = size;
+    hres = ObtainUserAgentString(0, str2, &size);
+    ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
+    ok(size == saved, "size=%d, expected %d\n", size, saved);
+    ok(strlen(expected) <= strlen(str2) &&
+       !memcmp(expected, str2, strlen(expected)*sizeof(CHAR)),
+       "user agent was \"%s\", expected to start with \"%s\"\n",
+       str2, expected);
+
+    size = saved+10;
+    hres = ObtainUserAgentString(0, str2, &size);
+    ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
+    ok(size == saved, "size=%d, expected %d\n", size, saved);
+
+    size = 0;
+    hres = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, NULL, 0, &size, 0);
+    ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
+    ok(size, "size == 0\n");
+
+    size = 0xdeadbeef;
+    hres = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, NULL, 1000, &size, 0);
+    ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
+    ok(size, "size == 0\n");
+
+    saved = size;
+    size = 0;
+    hres = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved+10, &size, 0);
+    ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
+    ok(size == saved, "size = %d, expected %d\n", size, saved);
+    ok(sizeof(expected) <= strlen(str2) && !memcmp(expected, str2, sizeof(expected)-1),
+       "user agent was \"%s\", expected to start with \"%s\"\n",
+       str2, expected);
+
+    size = 0;
+    str2[0] = 0;
+    hres = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
+    ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
+    ok(size == saved, "size = %d, expected %d\n", size, saved);
+    ok(sizeof(expected) <= strlen(str2) && !memcmp(expected, str2, sizeof(expected)-1),
+       "user agent was \"%s\", expected to start with \"%s\"\n",
+       str2, expected);
+
+    size = saved;
+    str2[0] = 0;
+    hres = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved-1, &size, 0);
+    ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
+    ok(size == saved, "size = %d, expected %d\n", size, saved);
+    ok(!str2[0], "buf changed\n");
+
+    size = saved;
+    str2[0] = 0;
+    hres = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, NULL, 0);
+    ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
+    ok(!str2[0], "buf changed\n");
+
+    hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, sizeof(test_str), 0);
+    ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
+
+    size = 0;
+    str2[0] = 0;
+    hres = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
+    ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
+    ok(size == sizeof(test_str) && !memcmp(str2, test_str, sizeof(test_str)), "wrong user agent\n");
+
+    hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test2_str, sizeof(test2_str), 0);
+    ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
+
+    size = 0;
+    str2[0] = 0;
+    hres = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
+    ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
+    ok(size == sizeof(test_str) && !memcmp(str2, test_str, sizeof(test_str)), "wrong user agent\n");
+
+    hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, 2, 0);
+    ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
+
+    size = 0;
+    str2[0] = 0;
+    hres = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
+    ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
+    ok(size == 3 && !strcmp(str2, "te"), "wrong user agent\n");
+
+    hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, 0, 0);
+    ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
+
+    hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, NULL, sizeof(test_str), 0);
+    ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
+
+    hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, NULL, 0, 0);
+    ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
+
     HeapFree(GetProcessHeap(), 0, str2);
 }
 
+static void test_MkParseDisplayNameEx(void)
+{
+    IMoniker *mon = NULL;
+    LPWSTR name;
+    DWORD issys;
+    ULONG eaten = 0;
+    IBindCtx *bctx;
+    HRESULT hres;
+
+    static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
+            '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
+            '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
+
+    CreateBindCtx(0, &bctx);
+
+    hres = MkParseDisplayNameEx(bctx, url9, &eaten, &mon);
+    ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
+    ok(eaten == sizeof(url9)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+    ok(mon != NULL, "mon == NULL\n");
+
+    hres = IMoniker_GetDisplayName(mon, NULL, 0, &name);
+    ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres);
+    ok(!lstrcmpW(name, url9), "wrong display name %s\n", wine_dbgstr_w(name));
+    CoTaskMemFree(name);
+
+    hres = IMoniker_IsSystemMoniker(mon, &issys);
+    ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
+    ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
+
+    IMoniker_Release(mon);
+
+    hres = MkParseDisplayNameEx(bctx, clsid_nameW, &eaten, &mon);
+    ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
+    ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+    ok(mon != NULL, "mon == NULL\n");
+
+    hres = IMoniker_IsSystemMoniker(mon, &issys);
+    ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
+    ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
+
+    IMoniker_Release(mon);
+
+    hres = MkParseDisplayNameEx(bctx, url8, &eaten, &mon);
+    ok(FAILED(hres), "MkParseDisplayNameEx succeeded: %08x\n", hres);
+
+    IBindCtx_Release(bctx);
+}
+
+static void test_IsValidURL(void)
+{
+    HRESULT hr;
+
+    hr = IsValidURL(NULL, 0, 0);
+    ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
+}
+
 START_TEST(misc)
 {
     OleInitialize(NULL);
@@ -1283,13 +1412,14 @@ START_TEST(misc)
     test_CoInternetCompareUrl();
     test_CoInternetQueryInfo();
     test_FindMimeFromData();
-    test_SecurityManager();
-    test_ZoneManager();
     test_NameSpace();
     test_MimeFilter();
     test_ReleaseBindInfo();
+    test_CopyStgMedium();
     test_UrlMkGetSessionOption();
-    test_ObtainUserAgentString();
+    test_user_agent();
+    test_MkParseDisplayNameEx();
+    test_IsValidURL();
 
     OleUninitialize();
 }