1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * Copyright 2005-2006 Jacek Caban for CodeWeavers
3*c2c66affSColin Finck  *
4*c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
5*c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
6*c2c66affSColin Finck  * License as published by the Free Software Foundation; either
7*c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
8*c2c66affSColin Finck  *
9*c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
10*c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12*c2c66affSColin Finck  * Lesser General Public License for more details.
13*c2c66affSColin Finck  *
14*c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
15*c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
16*c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17*c2c66affSColin Finck  */
18*c2c66affSColin Finck 
19*c2c66affSColin Finck #define WIN32_NO_STATUS
20*c2c66affSColin Finck #define _INC_WINDOWS
21*c2c66affSColin Finck #define COM_NO_WINDOWS_H
22*c2c66affSColin Finck 
23*c2c66affSColin Finck #define COBJMACROS
24*c2c66affSColin Finck #define CONST_VTABLE
25*c2c66affSColin Finck #define NONAMELESSUNION
26*c2c66affSColin Finck 
27*c2c66affSColin Finck #include <wine/test.h>
28*c2c66affSColin Finck //#include <stdarg.h>
29*c2c66affSColin Finck //#include <stddef.h>
30*c2c66affSColin Finck #include <stdio.h>
31*c2c66affSColin Finck 
32*c2c66affSColin Finck //#include "windef.h"
33*c2c66affSColin Finck //#include "winbase.h"
34*c2c66affSColin Finck #include <winreg.h>
35*c2c66affSColin Finck #include <winnls.h>
36*c2c66affSColin Finck #include <ole2.h>
37*c2c66affSColin Finck //#include "urlmon.h"
38*c2c66affSColin Finck 
39*c2c66affSColin Finck #include <initguid.h>
40*c2c66affSColin Finck 
41*c2c66affSColin Finck DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
42*c2c66affSColin Finck 
43*c2c66affSColin Finck #define DEFINE_EXPECT(func) \
44*c2c66affSColin Finck     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
45*c2c66affSColin Finck 
46*c2c66affSColin Finck #define SET_EXPECT(func) \
47*c2c66affSColin Finck     expect_ ## func = TRUE
48*c2c66affSColin Finck 
49*c2c66affSColin Finck #define CHECK_EXPECT(func) \
50*c2c66affSColin Finck     do { \
51*c2c66affSColin Finck         ok(expect_ ##func, "unexpected call " #func "\n"); \
52*c2c66affSColin Finck         expect_ ## func = FALSE; \
53*c2c66affSColin Finck         called_ ## func = TRUE; \
54*c2c66affSColin Finck     }while(0)
55*c2c66affSColin Finck 
56*c2c66affSColin Finck #define CHECK_EXPECT2(func) \
57*c2c66affSColin Finck     do { \
58*c2c66affSColin Finck         ok(expect_ ##func, "unexpected call " #func "\n"); \
59*c2c66affSColin Finck         called_ ## func = TRUE; \
60*c2c66affSColin Finck     }while(0)
61*c2c66affSColin Finck 
62*c2c66affSColin Finck #define CHECK_CALLED(func) \
63*c2c66affSColin Finck     do { \
64*c2c66affSColin Finck         ok(called_ ## func, "expected " #func "\n"); \
65*c2c66affSColin Finck         expect_ ## func = called_ ## func = FALSE; \
66*c2c66affSColin Finck     }while(0)
67*c2c66affSColin Finck 
68*c2c66affSColin Finck DEFINE_EXPECT(ParseUrl);
69*c2c66affSColin Finck DEFINE_EXPECT(QI_IInternetProtocolInfo);
70*c2c66affSColin Finck DEFINE_EXPECT(CreateInstance);
71*c2c66affSColin Finck DEFINE_EXPECT(unk_Release);
72*c2c66affSColin Finck 
73*c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetCompareUrl)(LPCWSTR, LPCWSTR, DWORD);
74*c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetGetSecurityUrl)(LPCWSTR, LPWSTR*, PSUACTION, DWORD);
75*c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession **, DWORD);
76*c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetParseUrl)(LPCWSTR, PARSEACTION, DWORD, LPWSTR, DWORD, DWORD *, DWORD);
77*c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetQueryInfo)(LPCWSTR, QUERYOPTION, DWORD, LPVOID, DWORD, DWORD *, DWORD);
78*c2c66affSColin Finck static HRESULT (WINAPI *pCopyStgMedium)(const STGMEDIUM *, STGMEDIUM *);
79*c2c66affSColin Finck static HRESULT (WINAPI *pCopyBindInfo)(const BINDINFO *, BINDINFO *);
80*c2c66affSColin Finck static HRESULT (WINAPI *pFindMimeFromData)(LPBC, LPCWSTR, LPVOID, DWORD, LPCWSTR,
81*c2c66affSColin Finck                         DWORD, LPWSTR*, DWORD);
82*c2c66affSColin Finck static HRESULT (WINAPI *pObtainUserAgentString)(DWORD, LPSTR, DWORD*);
83*c2c66affSColin Finck static HRESULT (WINAPI *pReleaseBindInfo)(BINDINFO*);
84*c2c66affSColin Finck static HRESULT (WINAPI *pUrlMkGetSessionOption)(DWORD, LPVOID, DWORD, DWORD *, DWORD);
85*c2c66affSColin Finck static HRESULT (WINAPI *pCompareSecurityIds)(BYTE*,DWORD,BYTE*,DWORD,DWORD);
86*c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetIsFeatureEnabled)(INTERNETFEATURELIST,DWORD);
87*c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetSetFeatureEnabled)(INTERNETFEATURELIST,DWORD,BOOL);
88*c2c66affSColin Finck static HRESULT (WINAPI *pIEInstallScope)(DWORD*);
89*c2c66affSColin Finck 
90*c2c66affSColin Finck static int strcmp_wa(const WCHAR *strw, const char *stra)
91*c2c66affSColin Finck {
92*c2c66affSColin Finck     WCHAR buf[512];
93*c2c66affSColin Finck     MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR));
94*c2c66affSColin Finck     return lstrcmpW(strw, buf);
95*c2c66affSColin Finck }
96*c2c66affSColin Finck 
97*c2c66affSColin Finck static void heap_free(void *mem)
98*c2c66affSColin Finck {
99*c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, mem);
100*c2c66affSColin Finck }
101*c2c66affSColin Finck 
102*c2c66affSColin Finck static WCHAR *a2w(const char *str)
103*c2c66affSColin Finck {
104*c2c66affSColin Finck     WCHAR *ret;
105*c2c66affSColin Finck     int len;
106*c2c66affSColin Finck 
107*c2c66affSColin Finck     if(!str)
108*c2c66affSColin Finck         return NULL;
109*c2c66affSColin Finck 
110*c2c66affSColin Finck     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
111*c2c66affSColin Finck     ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
112*c2c66affSColin Finck     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
113*c2c66affSColin Finck 
114*c2c66affSColin Finck     return ret;
115*c2c66affSColin Finck }
116*c2c66affSColin Finck 
117*c2c66affSColin Finck static void test_CreateFormatEnum(void)
118*c2c66affSColin Finck {
119*c2c66affSColin Finck     IEnumFORMATETC *fenum = NULL, *fenum2 = NULL;
120*c2c66affSColin Finck     FORMATETC fetc[5];
121*c2c66affSColin Finck     ULONG ul;
122*c2c66affSColin Finck     HRESULT hres;
123*c2c66affSColin Finck 
124*c2c66affSColin Finck     static DVTARGETDEVICE dev = {sizeof(dev),0,0,0,0,{0}};
125*c2c66affSColin Finck     static FORMATETC formatetc[] = {
126*c2c66affSColin Finck         {0,&dev,0,0,0},
127*c2c66affSColin Finck         {0,&dev,0,1,0},
128*c2c66affSColin Finck         {0,NULL,0,2,0},
129*c2c66affSColin Finck         {0,NULL,0,3,0},
130*c2c66affSColin Finck         {0,NULL,0,4,0}
131*c2c66affSColin Finck     };
132*c2c66affSColin Finck 
133*c2c66affSColin Finck     hres = CreateFormatEnumerator(0, formatetc, &fenum);
134*c2c66affSColin Finck     ok(hres == E_FAIL, "CreateFormatEnumerator failed: %08x, expected E_FAIL\n", hres);
135*c2c66affSColin Finck     hres = CreateFormatEnumerator(0, formatetc, NULL);
136*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "CreateFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
137*c2c66affSColin Finck     hres = CreateFormatEnumerator(5, formatetc, NULL);
138*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "CreateFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
139*c2c66affSColin Finck 
140*c2c66affSColin Finck 
141*c2c66affSColin Finck     hres = CreateFormatEnumerator(5, formatetc, &fenum);
142*c2c66affSColin Finck     ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
143*c2c66affSColin Finck     if(FAILED(hres))
144*c2c66affSColin Finck         return;
145*c2c66affSColin Finck 
146*c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 2, NULL, &ul);
147*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "Next failed: %08x, expected E_INVALIDARG\n", hres);
148*c2c66affSColin Finck     ul = 100;
149*c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 0, fetc, &ul);
150*c2c66affSColin Finck     ok(hres == S_OK, "Next failed: %08x\n", hres);
151*c2c66affSColin Finck     ok(ul == 0, "ul=%d, expected 0\n", ul);
152*c2c66affSColin Finck 
153*c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 2, fetc, &ul);
154*c2c66affSColin Finck     ok(hres == S_OK, "Next failed: %08x\n", hres);
155*c2c66affSColin Finck     ok(fetc[0].lindex == 0, "fetc[0].lindex=%d, expected 0\n", fetc[0].lindex);
156*c2c66affSColin Finck     ok(fetc[1].lindex == 1, "fetc[1].lindex=%d, expected 1\n", fetc[1].lindex);
157*c2c66affSColin Finck     ok(fetc[0].ptd == &dev, "fetc[0].ptd=%p, expected %p\n", fetc[0].ptd, &dev);
158*c2c66affSColin Finck     ok(ul == 2, "ul=%d, expected 2\n", ul);
159*c2c66affSColin Finck 
160*c2c66affSColin Finck     hres = IEnumFORMATETC_Skip(fenum, 1);
161*c2c66affSColin Finck     ok(hres == S_OK, "Skip failed: %08x\n", hres);
162*c2c66affSColin Finck 
163*c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 4, fetc, &ul);
164*c2c66affSColin Finck     ok(hres == S_FALSE, "Next failed: %08x, expected S_FALSE\n", hres);
165*c2c66affSColin Finck     ok(fetc[0].lindex == 3, "fetc[0].lindex=%d, expected 3\n", fetc[0].lindex);
166*c2c66affSColin Finck     ok(fetc[1].lindex == 4, "fetc[1].lindex=%d, expected 4\n", fetc[1].lindex);
167*c2c66affSColin Finck     ok(fetc[0].ptd == NULL, "fetc[0].ptd=%p, expected NULL\n", fetc[0].ptd);
168*c2c66affSColin Finck     ok(ul == 2, "ul=%d, expected 2\n", ul);
169*c2c66affSColin Finck 
170*c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 4, fetc, &ul);
171*c2c66affSColin Finck     ok(hres == S_FALSE, "Next failed: %08x, expected S_FALSE\n", hres);
172*c2c66affSColin Finck     ok(ul == 0, "ul=%d, expected 0\n", ul);
173*c2c66affSColin Finck     ul = 100;
174*c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 0, fetc, &ul);
175*c2c66affSColin Finck     ok(hres == S_OK, "Next failed: %08x\n", hres);
176*c2c66affSColin Finck     ok(ul == 0, "ul=%d, expected 0\n", ul);
177*c2c66affSColin Finck 
178*c2c66affSColin Finck     hres = IEnumFORMATETC_Skip(fenum, 3);
179*c2c66affSColin Finck     ok(hres == S_FALSE, "Skip failed: %08x, expected S_FALSE\n", hres);
180*c2c66affSColin Finck 
181*c2c66affSColin Finck     hres = IEnumFORMATETC_Reset(fenum);
182*c2c66affSColin Finck     ok(hres == S_OK, "Reset failed: %08x\n", hres);
183*c2c66affSColin Finck 
184*c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 5, fetc, NULL);
185*c2c66affSColin Finck     ok(hres == S_OK, "Next failed: %08x\n", hres);
186*c2c66affSColin Finck     ok(fetc[0].lindex == 0, "fetc[0].lindex=%d, expected 0\n", fetc[0].lindex);
187*c2c66affSColin Finck 
188*c2c66affSColin Finck     hres = IEnumFORMATETC_Reset(fenum);
189*c2c66affSColin Finck     ok(hres == S_OK, "Reset failed: %08x\n", hres);
190*c2c66affSColin Finck 
191*c2c66affSColin Finck     hres = IEnumFORMATETC_Skip(fenum, 2);
192*c2c66affSColin Finck     ok(hres == S_OK, "Skip failed: %08x\n", hres);
193*c2c66affSColin Finck 
194*c2c66affSColin Finck     hres = IEnumFORMATETC_Clone(fenum, NULL);
195*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "Clone failed: %08x, expected E_INVALIDARG\n", hres);
196*c2c66affSColin Finck 
197*c2c66affSColin Finck     hres = IEnumFORMATETC_Clone(fenum, &fenum2);
198*c2c66affSColin Finck     ok(hres == S_OK, "Clone failed: %08x\n", hres);
199*c2c66affSColin Finck 
200*c2c66affSColin Finck     if(SUCCEEDED(hres)) {
201*c2c66affSColin Finck         ok(fenum != fenum2, "fenum == fenum2\n");
202*c2c66affSColin Finck 
203*c2c66affSColin Finck         hres = IEnumFORMATETC_Next(fenum2, 2, fetc, &ul);
204*c2c66affSColin Finck         ok(hres == S_OK, "Next failed: %08x\n", hres);
205*c2c66affSColin Finck         ok(fetc[0].lindex == 2, "fetc[0].lindex=%d, expected 2\n", fetc[0].lindex);
206*c2c66affSColin Finck 
207*c2c66affSColin Finck         IEnumFORMATETC_Release(fenum2);
208*c2c66affSColin Finck     }
209*c2c66affSColin Finck 
210*c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 2, fetc, &ul);
211*c2c66affSColin Finck     ok(hres == S_OK, "Next failed: %08x\n", hres);
212*c2c66affSColin Finck     ok(fetc[0].lindex == 2, "fetc[0].lindex=%d, expected 2\n", fetc[0].lindex);
213*c2c66affSColin Finck 
214*c2c66affSColin Finck     hres = IEnumFORMATETC_Skip(fenum, 1);
215*c2c66affSColin Finck     ok(hres == S_OK, "Skip failed: %08x\n", hres);
216*c2c66affSColin Finck 
217*c2c66affSColin Finck     IEnumFORMATETC_Release(fenum);
218*c2c66affSColin Finck }
219*c2c66affSColin Finck 
220*c2c66affSColin Finck static void test_RegisterFormatEnumerator(void)
221*c2c66affSColin Finck {
222*c2c66affSColin Finck     IBindCtx *bctx = NULL;
223*c2c66affSColin Finck     IEnumFORMATETC *format = NULL, *format2 = NULL;
224*c2c66affSColin Finck     IUnknown *unk = NULL;
225*c2c66affSColin Finck     HRESULT hres;
226*c2c66affSColin Finck 
227*c2c66affSColin Finck     static FORMATETC formatetc = {0,NULL,0,0,0};
228*c2c66affSColin Finck     static WCHAR wszEnumFORMATETC[] =
229*c2c66affSColin Finck         {'_','E','n','u','m','F','O','R','M','A','T','E','T','C','_',0};
230*c2c66affSColin Finck 
231*c2c66affSColin Finck     CreateBindCtx(0, &bctx);
232*c2c66affSColin Finck 
233*c2c66affSColin Finck     hres = CreateFormatEnumerator(1, &formatetc, &format);
234*c2c66affSColin Finck     ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
235*c2c66affSColin Finck     if(FAILED(hres))
236*c2c66affSColin Finck         return;
237*c2c66affSColin Finck 
238*c2c66affSColin Finck     hres = RegisterFormatEnumerator(NULL, format, 0);
239*c2c66affSColin Finck     ok(hres == E_INVALIDARG,
240*c2c66affSColin Finck             "RegisterFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
241*c2c66affSColin Finck     hres = RegisterFormatEnumerator(bctx, NULL, 0);
242*c2c66affSColin Finck     ok(hres == E_INVALIDARG,
243*c2c66affSColin Finck             "RegisterFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
244*c2c66affSColin Finck 
245*c2c66affSColin Finck     hres = RegisterFormatEnumerator(bctx, format, 0);
246*c2c66affSColin Finck     ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
247*c2c66affSColin Finck 
248*c2c66affSColin Finck     hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
249*c2c66affSColin Finck     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
250*c2c66affSColin Finck     ok(unk == (IUnknown*)format, "unk != format\n");
251*c2c66affSColin Finck 
252*c2c66affSColin Finck     hres = RevokeFormatEnumerator(NULL, format);
253*c2c66affSColin Finck     ok(hres == E_INVALIDARG,
254*c2c66affSColin Finck             "RevokeFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
255*c2c66affSColin Finck 
256*c2c66affSColin Finck     hres = RevokeFormatEnumerator(bctx, format);
257*c2c66affSColin Finck     ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
258*c2c66affSColin Finck 
259*c2c66affSColin Finck     hres = RevokeFormatEnumerator(bctx, format);
260*c2c66affSColin Finck     ok(hres == E_FAIL, "RevokeFormatEnumerator failed: %08x, expected E_FAIL\n", hres);
261*c2c66affSColin Finck 
262*c2c66affSColin Finck     hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
263*c2c66affSColin Finck     ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
264*c2c66affSColin Finck 
265*c2c66affSColin Finck     hres = RegisterFormatEnumerator(bctx, format, 0);
266*c2c66affSColin Finck     ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
267*c2c66affSColin Finck 
268*c2c66affSColin Finck     hres = CreateFormatEnumerator(1, &formatetc, &format2);
269*c2c66affSColin Finck     ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
270*c2c66affSColin Finck 
271*c2c66affSColin Finck     if(SUCCEEDED(hres)) {
272*c2c66affSColin Finck         hres = RevokeFormatEnumerator(bctx, format);
273*c2c66affSColin Finck         ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
274*c2c66affSColin Finck 
275*c2c66affSColin Finck         IEnumFORMATETC_Release(format2);
276*c2c66affSColin Finck     }
277*c2c66affSColin Finck 
278*c2c66affSColin Finck     hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
279*c2c66affSColin Finck     ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
280*c2c66affSColin Finck 
281*c2c66affSColin Finck     IEnumFORMATETC_Release(format);
282*c2c66affSColin Finck 
283*c2c66affSColin Finck     hres = RegisterFormatEnumerator(bctx, format, 0);
284*c2c66affSColin Finck     ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
285*c2c66affSColin Finck     hres = RevokeFormatEnumerator(bctx, NULL);
286*c2c66affSColin Finck     ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
287*c2c66affSColin Finck     hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
288*c2c66affSColin Finck     ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
289*c2c66affSColin Finck 
290*c2c66affSColin Finck     IEnumFORMATETC_Release(format);
291*c2c66affSColin Finck     IBindCtx_Release(bctx);
292*c2c66affSColin Finck }
293*c2c66affSColin Finck static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',
294*c2c66affSColin Finck         '/','b','l','a','n','k','.','h','t','m',0};
295*c2c66affSColin Finck static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
296*c2c66affSColin Finck static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0};
297*c2c66affSColin Finck static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
298*c2c66affSColin Finck         '%','2','e','j','p','g',0};
299*c2c66affSColin Finck static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
300*c2c66affSColin Finck         '.','o','r','g',0};
301*c2c66affSColin Finck static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
302*c2c66affSColin Finck static const WCHAR url7[] = {'f','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',
303*c2c66affSColin Finck         'f','i','l','e','.','t','e','s','t',0};
304*c2c66affSColin Finck static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
305*c2c66affSColin Finck static const WCHAR url9[] =
306*c2c66affSColin Finck     {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
307*c2c66affSColin Finck      '/','s','i','t','e','/','a','b','o','u','t',0};
308*c2c66affSColin Finck static const WCHAR url10[] = {'h','t','t','p',':','/','/','g','o','o','g','l','e','.','*','.',
309*c2c66affSColin Finck         'c','o','m',0};
310*c2c66affSColin Finck static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
311*c2c66affSColin Finck         '.','j','p','g',0};
312*c2c66affSColin Finck 
313*c2c66affSColin Finck static const WCHAR path3[] = {'c',':','\\','I','n','d','e','x','.','h','t','m',0};
314*c2c66affSColin Finck static const WCHAR path4[] = {'s','o','m','e',' ','f','i','l','e','.','j','p','g',0};
315*c2c66affSColin Finck 
316*c2c66affSColin Finck static const WCHAR wszRes[] = {'r','e','s',0};
317*c2c66affSColin Finck static const WCHAR wszFile[] = {'f','i','l','e',0};
318*c2c66affSColin Finck static const WCHAR wszHttp[] = {'h','t','t','p',0};
319*c2c66affSColin Finck static const WCHAR wszAbout[] = {'a','b','o','u','t',0};
320*c2c66affSColin Finck static const WCHAR wszEmpty[] = {0};
321*c2c66affSColin Finck static const WCHAR wszGoogle[] = {'g','o','o','g','l','e','.','*','.','c','o','m',0};
322*c2c66affSColin Finck 
323*c2c66affSColin Finck static const WCHAR wszWineHQ[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
324*c2c66affSColin Finck static const WCHAR wszHttpWineHQ[] = {'h','t','t','p',':','/','/','w','w','w','.',
325*c2c66affSColin Finck     'w','i','n','e','h','q','.','o','r','g',0};
326*c2c66affSColin Finck static const WCHAR wszHttpGoogle[] = {'h','t','t','p',':','/','/','g','o','o','g','l','e',
327*c2c66affSColin Finck     '.','*','.','c','o','m',0};
328*c2c66affSColin Finck 
329*c2c66affSColin Finck struct parse_test {
330*c2c66affSColin Finck     LPCWSTR url;
331*c2c66affSColin Finck     HRESULT secur_hres;
332*c2c66affSColin Finck     LPCWSTR encoded_url;
333*c2c66affSColin Finck     HRESULT path_hres;
334*c2c66affSColin Finck     LPCWSTR path;
335*c2c66affSColin Finck     LPCWSTR schema;
336*c2c66affSColin Finck     LPCWSTR domain;
337*c2c66affSColin Finck     HRESULT domain_hres;
338*c2c66affSColin Finck     LPCWSTR rootdocument;
339*c2c66affSColin Finck     HRESULT rootdocument_hres;
340*c2c66affSColin Finck };
341*c2c66affSColin Finck 
342*c2c66affSColin Finck static const struct parse_test parse_tests[] = {
343*c2c66affSColin Finck     {url1, S_OK,   url1,  E_INVALIDARG, NULL, wszRes, NULL, E_FAIL, NULL, E_FAIL},
344*c2c66affSColin Finck     {url2, E_FAIL, url2,  E_INVALIDARG, NULL, wszEmpty, NULL, E_FAIL, NULL, E_FAIL},
345*c2c66affSColin Finck     {url3, E_FAIL, url3,  S_OK, path3,        wszFile, wszEmpty, S_OK, NULL, E_FAIL},
346*c2c66affSColin Finck     {url4, E_FAIL, url4e, S_OK, path4,        wszFile, wszEmpty, S_OK, NULL, E_FAIL},
347*c2c66affSColin Finck     {url5, E_FAIL, url5,  E_INVALIDARG, NULL, wszHttp, wszWineHQ, S_OK, wszHttpWineHQ, S_OK},
348*c2c66affSColin Finck     {url6, S_OK,   url6,  E_INVALIDARG, NULL, wszAbout, NULL, E_FAIL, NULL, E_FAIL},
349*c2c66affSColin Finck     {url10, E_FAIL, url10, E_INVALIDARG,NULL, wszHttp, wszGoogle, S_OK, wszHttpGoogle, S_OK}
350*c2c66affSColin Finck };
351*c2c66affSColin Finck 
352*c2c66affSColin Finck static void test_CoInternetParseUrl(void)
353*c2c66affSColin Finck {
354*c2c66affSColin Finck     HRESULT hres;
355*c2c66affSColin Finck     DWORD size;
356*c2c66affSColin Finck     int i;
357*c2c66affSColin Finck 
358*c2c66affSColin Finck     static WCHAR buf[4096];
359*c2c66affSColin Finck 
360*c2c66affSColin Finck     memset(buf, 0xf0, sizeof(buf));
361*c2c66affSColin Finck     hres = pCoInternetParseUrl(parse_tests[0].url, PARSE_SCHEMA, 0, buf,
362*c2c66affSColin Finck             3, &size, 0);
363*c2c66affSColin Finck     ok(hres == E_POINTER, "schema failed: %08x, expected E_POINTER\n", hres);
364*c2c66affSColin Finck 
365*c2c66affSColin Finck     for(i=0; i < sizeof(parse_tests)/sizeof(parse_tests[0]); i++) {
366*c2c66affSColin Finck         memset(buf, 0xf0, sizeof(buf));
367*c2c66affSColin Finck         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_SECURITY_URL, 0, buf,
368*c2c66affSColin Finck                 sizeof(buf)/sizeof(WCHAR), &size, 0);
369*c2c66affSColin Finck         ok(hres == parse_tests[i].secur_hres, "[%d] security url failed: %08x, expected %08x\n",
370*c2c66affSColin Finck                 i, hres, parse_tests[i].secur_hres);
371*c2c66affSColin Finck 
372*c2c66affSColin Finck         memset(buf, 0xf0, sizeof(buf));
373*c2c66affSColin Finck         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_ENCODE, 0, buf,
374*c2c66affSColin Finck                 sizeof(buf)/sizeof(WCHAR), &size, 0);
375*c2c66affSColin Finck         ok(hres == S_OK, "[%d] encoding failed: %08x\n", i, hres);
376*c2c66affSColin Finck         ok(size == lstrlenW(parse_tests[i].encoded_url), "[%d] wrong size\n", i);
377*c2c66affSColin Finck         ok(!lstrcmpW(parse_tests[i].encoded_url, buf), "[%d] wrong encoded url\n", i);
378*c2c66affSColin Finck 
379*c2c66affSColin Finck         memset(buf, 0xf0, sizeof(buf));
380*c2c66affSColin Finck         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_PATH_FROM_URL, 0, buf,
381*c2c66affSColin Finck                 sizeof(buf)/sizeof(WCHAR), &size, 0);
382*c2c66affSColin Finck         ok(hres == parse_tests[i].path_hres, "[%d] path failed: %08x, expected %08x\n",
383*c2c66affSColin Finck                 i, hres, parse_tests[i].path_hres);
384*c2c66affSColin Finck         if(parse_tests[i].path) {
385*c2c66affSColin Finck             ok(size == lstrlenW(parse_tests[i].path), "[%d] wrong size\n", i);
386*c2c66affSColin Finck             ok(!lstrcmpW(parse_tests[i].path, buf), "[%d] wrong path\n", i);
387*c2c66affSColin Finck         }
388*c2c66affSColin Finck 
389*c2c66affSColin Finck         memset(buf, 0xf0, sizeof(buf));
390*c2c66affSColin Finck         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_SCHEMA, 0, buf,
391*c2c66affSColin Finck                 sizeof(buf)/sizeof(WCHAR), &size, 0);
392*c2c66affSColin Finck         ok(hres == S_OK, "[%d] schema failed: %08x\n", i, hres);
393*c2c66affSColin Finck         ok(size == lstrlenW(parse_tests[i].schema), "[%d] wrong size\n", i);
394*c2c66affSColin Finck         ok(!lstrcmpW(parse_tests[i].schema, buf), "[%d] wrong schema\n", i);
395*c2c66affSColin Finck 
396*c2c66affSColin Finck         if(memcmp(parse_tests[i].url, wszRes, 3*sizeof(WCHAR))
397*c2c66affSColin Finck                 && memcmp(parse_tests[i].url, wszAbout, 5*sizeof(WCHAR))) {
398*c2c66affSColin Finck             memset(buf, 0xf0, sizeof(buf));
399*c2c66affSColin Finck             hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_DOMAIN, 0, buf,
400*c2c66affSColin Finck                     sizeof(buf)/sizeof(WCHAR), &size, 0);
401*c2c66affSColin Finck             ok(hres == parse_tests[i].domain_hres, "[%d] domain failed: %08x\n", i, hres);
402*c2c66affSColin Finck             if(parse_tests[i].domain)
403*c2c66affSColin Finck                 ok(!lstrcmpW(parse_tests[i].domain, buf), "[%d] wrong domain, received %s\n", i, wine_dbgstr_w(buf));
404*c2c66affSColin Finck         }
405*c2c66affSColin Finck 
406*c2c66affSColin Finck         memset(buf, 0xf0, sizeof(buf));
407*c2c66affSColin Finck         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_ROOTDOCUMENT, 0, buf,
408*c2c66affSColin Finck                 sizeof(buf)/sizeof(WCHAR), &size, 0);
409*c2c66affSColin Finck         ok(hres == parse_tests[i].rootdocument_hres, "[%d] rootdocument failed: %08x\n", i, hres);
410*c2c66affSColin Finck         if(parse_tests[i].rootdocument)
411*c2c66affSColin Finck             ok(!lstrcmpW(parse_tests[i].rootdocument, buf), "[%d] wrong rootdocument, received %s\n", i, wine_dbgstr_w(buf));
412*c2c66affSColin Finck     }
413*c2c66affSColin Finck }
414*c2c66affSColin Finck 
415*c2c66affSColin Finck static void test_CoInternetCompareUrl(void)
416*c2c66affSColin Finck {
417*c2c66affSColin Finck     HRESULT hres;
418*c2c66affSColin Finck 
419*c2c66affSColin Finck     hres = pCoInternetCompareUrl(url1, url1, 0);
420*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetCompareUrl failed: %08x\n", hres);
421*c2c66affSColin Finck 
422*c2c66affSColin Finck     hres = pCoInternetCompareUrl(url1, url3, 0);
423*c2c66affSColin Finck     ok(hres == S_FALSE, "CoInternetCompareUrl failed: %08x\n", hres);
424*c2c66affSColin Finck 
425*c2c66affSColin Finck     hres = pCoInternetCompareUrl(url3, url1, 0);
426*c2c66affSColin Finck     ok(hres == S_FALSE, "CoInternetCompareUrl failed: %08x\n", hres);
427*c2c66affSColin Finck }
428*c2c66affSColin Finck 
429*c2c66affSColin Finck static const struct {
430*c2c66affSColin Finck     LPCWSTR url;
431*c2c66affSColin Finck     DWORD uses_net;
432*c2c66affSColin Finck } query_info_tests[] = {
433*c2c66affSColin Finck     {url1, 0},
434*c2c66affSColin Finck     {url2, 0},
435*c2c66affSColin Finck     {url3, 0},
436*c2c66affSColin Finck     {url4, 0},
437*c2c66affSColin Finck     {url5, 0},
438*c2c66affSColin Finck     {url6, 0},
439*c2c66affSColin Finck     {url7, 0},
440*c2c66affSColin Finck     {url8, 0}
441*c2c66affSColin Finck };
442*c2c66affSColin Finck 
443*c2c66affSColin Finck static void test_CoInternetQueryInfo(void)
444*c2c66affSColin Finck {
445*c2c66affSColin Finck     BYTE buf[100];
446*c2c66affSColin Finck     DWORD cb, i;
447*c2c66affSColin Finck     HRESULT hres;
448*c2c66affSColin Finck 
449*c2c66affSColin Finck     for(i=0; i < sizeof(query_info_tests)/sizeof(query_info_tests[0]); i++) {
450*c2c66affSColin Finck         cb = 0xdeadbeef;
451*c2c66affSColin Finck         memset(buf, '?', sizeof(buf));
452*c2c66affSColin Finck         hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), &cb, 0);
453*c2c66affSColin Finck         ok(hres == S_OK, "[%d] CoInternetQueryInfo failed: %08x\n", i, hres);
454*c2c66affSColin Finck         ok(cb == sizeof(DWORD), "[%d] cb = %d\n", i, cb);
455*c2c66affSColin Finck         ok(*(DWORD*)buf == query_info_tests[i].uses_net, "[%d] ret %x, expected %x\n",
456*c2c66affSColin Finck            i, *(DWORD*)buf, query_info_tests[i].uses_net);
457*c2c66affSColin Finck 
458*c2c66affSColin Finck         hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, 3, &cb, 0);
459*c2c66affSColin Finck         ok(hres == E_FAIL, "[%d] CoInternetQueryInfo failed: %08x, expected E_FAIL\n", i, hres);
460*c2c66affSColin Finck         hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, NULL, sizeof(buf), &cb, 0);
461*c2c66affSColin Finck         ok(hres == E_FAIL, "[%d] CoInternetQueryInfo failed: %08x, expected E_FAIL\n", i, hres);
462*c2c66affSColin Finck 
463*c2c66affSColin Finck         memset(buf, '?', sizeof(buf));
464*c2c66affSColin Finck         hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), NULL, 0);
465*c2c66affSColin Finck         ok(hres == S_OK, "[%d] CoInternetQueryInfo failed: %08x\n", i, hres);
466*c2c66affSColin Finck         ok(*(DWORD*)buf == query_info_tests[i].uses_net, "[%d] ret %x, expected %x\n",
467*c2c66affSColin Finck            i, *(DWORD*)buf, query_info_tests[i].uses_net);
468*c2c66affSColin Finck     }
469*c2c66affSColin Finck }
470*c2c66affSColin Finck 
471*c2c66affSColin Finck static const struct {
472*c2c66affSColin Finck     const char *url;
473*c2c66affSColin Finck     const char *mime;
474*c2c66affSColin Finck     HRESULT hres;
475*c2c66affSColin Finck     BOOL broken_failure;
476*c2c66affSColin Finck     const char *broken_mime;
477*c2c66affSColin Finck } mime_tests[] = {
478*c2c66affSColin Finck     {"res://mshtml.dll/blank.htm", "text/html", S_OK},
479*c2c66affSColin Finck     {"index.htm", "text/html", S_OK},
480*c2c66affSColin Finck     {"file://c:\\Index.htm", "text/html", S_OK},
481*c2c66affSColin Finck     {"file://c:\\Index.htm?q=test", "text/html", S_OK, TRUE},
482*c2c66affSColin Finck     {"file://c:\\Index.htm#hash_part", "text/html", S_OK, TRUE},
483*c2c66affSColin Finck     {"file://c:\\Index.htm#hash_part.txt", "text/html", S_OK, FALSE, "text/plain"},
484*c2c66affSColin Finck     {"file://some%20file%2ejpg", NULL, E_FAIL},
485*c2c66affSColin Finck     {"http://www.winehq.org", NULL, __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)},
486*c2c66affSColin Finck     {"about:blank", NULL, E_FAIL},
487*c2c66affSColin Finck     {"ftp://winehq.org/file.test", NULL, __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)}
488*c2c66affSColin Finck };
489*c2c66affSColin Finck 
490*c2c66affSColin Finck static BYTE data1[] = "test data\n";
491*c2c66affSColin Finck static BYTE data2[] = {31,'t','e','s',0xfa,'t',' ','d','a','t','a','\n',0};
492*c2c66affSColin Finck static BYTE data3[] = {0,0,0};
493*c2c66affSColin Finck static BYTE data4[] = {'t','e','s',0xfa,'t',' ','d','a','t','a','\n',0,0};
494*c2c66affSColin Finck static BYTE data5[] = {0xa,0xa,0xa,'x',32,'x',0};
495*c2c66affSColin Finck static BYTE data6[] = {0xfa,0xfa,0xfa,0xfa,'\n','\r','\t','x','x','x',1};
496*c2c66affSColin Finck static BYTE data7[] = "<html>blahblah";
497*c2c66affSColin Finck static BYTE data8[] = {'t','e','s',0xfa,'t',' ','<','h','t','m','l','>','d','a','t','a','\n',0,0};
498*c2c66affSColin Finck static BYTE data9[] = {'t','e',0,'s',0xfa,'t',' ','<','h','t','m','l','>','d','a','t','a','\n',0,0};
499*c2c66affSColin Finck static BYTE data10[] = "<HtmL>blahblah";
500*c2c66affSColin Finck static BYTE data11[] = "blah<HTML>blahblah";
501*c2c66affSColin Finck static BYTE data12[] = "blah<HTMLblahblah";
502*c2c66affSColin Finck static BYTE data13[] = "blahHTML>blahblah";
503*c2c66affSColin Finck static BYTE data14[] = "blah<HTMblahblah";
504*c2c66affSColin Finck static BYTE data15[] = {0xff,0xd8};
505*c2c66affSColin Finck static BYTE data16[] = {0xff,0xd8,'h'};
506*c2c66affSColin Finck static BYTE data17[] = {0,0xff,0xd8};
507*c2c66affSColin Finck static BYTE data18[] = {0xff,0xd8,'<','h','t','m','l','>'};
508*c2c66affSColin Finck static BYTE data19[] = {'G','I','F','8','7','a'};
509*c2c66affSColin Finck static BYTE data20[] = {'G','I','F','8','9','a'};
510*c2c66affSColin Finck static BYTE data21[] = {'G','I','F','8','7'};
511*c2c66affSColin Finck static BYTE data22[] = {'G','i','F','8','7','a'};
512*c2c66affSColin Finck static BYTE data23[] = {'G','i','F','8','8','a'};
513*c2c66affSColin Finck static BYTE data24[] = {'g','i','f','8','7','a'};
514*c2c66affSColin Finck static BYTE data25[] = {'G','i','F','8','7','A'};
515*c2c66affSColin Finck static BYTE data26[] = {'G','i','F','8','7','a','<','h','t','m','l','>'};
516*c2c66affSColin Finck static BYTE data27[] = {0x30,'G','i','F','8','7','A'};
517*c2c66affSColin Finck static BYTE data28[] = {0x42,0x4d,0x6e,0x42,0x1c,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00};
518*c2c66affSColin Finck static BYTE data29[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x','x'};
519*c2c66affSColin Finck static BYTE data30[] = {0x42,0x4d,'x','x','x','x',0x00,0x01,0x00,0x00,'x','x','x','x'};
520*c2c66affSColin Finck static BYTE data31[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'<','h','t','m','l','>'};
521*c2c66affSColin Finck static BYTE data32[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x'};
522*c2c66affSColin Finck static BYTE data33[] = {0x00,0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x'};
523*c2c66affSColin Finck static BYTE data34[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x'};
524*c2c66affSColin Finck static BYTE data35[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x','x','x','x',0};
525*c2c66affSColin Finck static BYTE data36[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,'x','x'};
526*c2c66affSColin Finck static BYTE data37[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'<','h','t','m','l','>'};
527*c2c66affSColin Finck static BYTE data38[] = {0x00,0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x'};
528*c2c66affSColin Finck static BYTE data39[] = {0x4d,0x4d,0x00,0x2a,0xff};
529*c2c66affSColin Finck static BYTE data40[] = {0x4d,0x4d,0x00,0x2a,'<','h','t','m','l','>',0};
530*c2c66affSColin Finck static BYTE data41[] = {0x4d,0x4d,0xff};
531*c2c66affSColin Finck static BYTE data42[] = {0x4d,0x4d};
532*c2c66affSColin Finck static BYTE data43[] = {0x00,0x4d,0x4d,0x00};
533*c2c66affSColin Finck static BYTE data44[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20,0xff};
534*c2c66affSColin Finck static BYTE data45[] = {'R','I','F','f',0xff,0xff,0xff,0xff,'A','V','I',0x20,0xff};
535*c2c66affSColin Finck static BYTE data46[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20};
536*c2c66affSColin Finck static BYTE data47[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x21,0xff};
537*c2c66affSColin Finck static BYTE data48[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20,'<','h','t','m','l','>'};
538*c2c66affSColin Finck static BYTE data49[] = {'R','I','F','F',0x0f,0x0f,0xf0,0xf0,'A','V','I',0x20,0xf0,0x00};
539*c2c66affSColin Finck static BYTE data50[] = {0x00,0x00,0x01,0xb3,0xff};
540*c2c66affSColin Finck static BYTE data51[] = {0x00,0x00,0x01,0xba,0xff};
541*c2c66affSColin Finck static BYTE data52[] = {0x00,0x00,0x01,0xb8,0xff};
542*c2c66affSColin Finck static BYTE data53[] = {0x00,0x00,0x01,0xba};
543*c2c66affSColin Finck static BYTE data54[] = {0x00,0x00,0x01,0xba,'<','h','t','m','l','>'};
544*c2c66affSColin Finck static BYTE data55[] = {0x1f,0x8b,'x'};
545*c2c66affSColin Finck static BYTE data56[] = {0x1f};
546*c2c66affSColin Finck static BYTE data57[] = {0x1f,0x8b,'<','h','t','m','l','>','t','e','s','t',0};
547*c2c66affSColin Finck static BYTE data58[] = {0x1f,0x8b};
548*c2c66affSColin Finck static BYTE data59[] = {0x50,0x4b,'x'};
549*c2c66affSColin Finck static BYTE data60[] = {0x50,0x4b};
550*c2c66affSColin Finck static BYTE data61[] = {0x50,0x4b,'<','h','t','m','l','>',0};
551*c2c66affSColin Finck static BYTE data62[] = {0xca,0xfe,0xba,0xbe,'x'};
552*c2c66affSColin Finck static BYTE data63[] = {0xca,0xfe,0xba,0xbe};
553*c2c66affSColin Finck static BYTE data64[] = {0xca,0xfe,0xba,0xbe,'<','h','t','m','l','>',0};
554*c2c66affSColin Finck static BYTE data65[] = {0x25,0x50,0x44,0x46,'x'};
555*c2c66affSColin Finck static BYTE data66[] = {0x25,0x50,0x44,0x46};
556*c2c66affSColin Finck static BYTE data67[] = {0x25,0x50,0x44,0x46,'x','<','h','t','m','l','>'};
557*c2c66affSColin Finck static BYTE data68[] = {'M','Z','x'};
558*c2c66affSColin Finck static BYTE data69[] = {'M','Z'};
559*c2c66affSColin Finck static BYTE data70[] = {'M','Z','<','h','t','m','l','>',0xff};
560*c2c66affSColin Finck static BYTE data71[] = {'{','\\','r','t','f',0};
561*c2c66affSColin Finck static BYTE data72[] = {'{','\\','r','t','f'};
562*c2c66affSColin Finck static BYTE data73[] = {' ','{','\\','r','t','f',' '};
563*c2c66affSColin Finck static BYTE data74[] = {'{','\\','r','t','f','<','h','t','m','l','>',' '};
564*c2c66affSColin Finck static BYTE data75[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V','E',0xff};
565*c2c66affSColin Finck static BYTE data76[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V','E'};
566*c2c66affSColin Finck static BYTE data77[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V',0xff,0xff};
567*c2c66affSColin Finck static BYTE data78[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'<','h','t','m','l','>',0xff};
568*c2c66affSColin Finck static BYTE data79[] = {'%','!',0xff};
569*c2c66affSColin Finck static BYTE data80[] = {'%','!'};
570*c2c66affSColin Finck static BYTE data81[] = {'%','!','P','S','<','h','t','m','l','>'};
571*c2c66affSColin Finck static BYTE data82[] = {'.','s','n','d',0};
572*c2c66affSColin Finck static BYTE data83[] = {'.','s','n','d'};
573*c2c66affSColin Finck static BYTE data84[] = {'.','s','n','d',0,'<','h','t','m','l','>',1,1};
574*c2c66affSColin Finck static BYTE data85[] = {'.','S','N','D',0};
575*c2c66affSColin Finck static BYTE data86[] = {0x49,0x49,0x2a,0xff};
576*c2c66affSColin Finck static BYTE data87[] = {' ','<','h','e','a','d'};
577*c2c66affSColin Finck static BYTE data88[] = {' ','<','h','e','a','d','>'};
578*c2c66affSColin Finck static BYTE data89[] = {'\t','\r','<','h','e','a','d','>'};
579*c2c66affSColin Finck static BYTE data90[] = {'<','H','e','A','d',' '};
580*c2c66affSColin Finck static BYTE data91[] = {'<','?','x','m','l',' ',0};
581*c2c66affSColin Finck static BYTE data92[] = {'a','b','c','<','?','x','m','l',' ',' '};
582*c2c66affSColin Finck static BYTE data93[] = {'<','?','x','m','l',' ',' ','<','h','t','m','l','>'};
583*c2c66affSColin Finck static BYTE data94[] = {'<','h','t','m','l','>','<','?','x','m','l',' ',' '};
584*c2c66affSColin Finck static BYTE data95[] = {'{','\\','r','t','f','<','?','x','m','l',' ',' '};
585*c2c66affSColin Finck static BYTE data96[] = {'<','?','x','m','l',' '};
586*c2c66affSColin Finck static BYTE data97[] = "<body";
587*c2c66affSColin Finck static BYTE data98[] = "blah<BoDyblahblah";
588*c2c66affSColin Finck 
589*c2c66affSColin Finck static const struct {
590*c2c66affSColin Finck     BYTE *data;
591*c2c66affSColin Finck     DWORD size;
592*c2c66affSColin Finck     const char *mime;
593*c2c66affSColin Finck     const char *mime_pjpeg;
594*c2c66affSColin Finck     const char *broken_mime;
595*c2c66affSColin Finck     const char *url;
596*c2c66affSColin Finck     const char *proposed_mime;
597*c2c66affSColin Finck } mime_tests2[] = {
598*c2c66affSColin Finck     {data1, sizeof(data1), "text/plain"},
599*c2c66affSColin Finck     {data2, sizeof(data2), "application/octet-stream", "image/pjpeg"},
600*c2c66affSColin Finck     {data3, sizeof(data3), "application/octet-stream", "image/pjpeg"},
601*c2c66affSColin Finck     {data4, sizeof(data4), "application/octet-stream", "image/pjpeg"},
602*c2c66affSColin Finck     {data5, sizeof(data5), "text/plain"},
603*c2c66affSColin Finck     {data6, sizeof(data6), "text/plain"},
604*c2c66affSColin Finck     {data7, sizeof(data7), "text/html", "text/plain"},
605*c2c66affSColin Finck     {data8, sizeof(data8), "text/html", "text/plain"},
606*c2c66affSColin Finck     {data9, sizeof(data9), "text/html", "image/pjpeg"},
607*c2c66affSColin Finck     {data10, sizeof(data10), "text/html", "text/plain"},
608*c2c66affSColin Finck     {data11, sizeof(data11), "text/html", "text/plain"},
609*c2c66affSColin Finck     {data12, sizeof(data12), "text/html", "text/plain"},
610*c2c66affSColin Finck     {data13, sizeof(data13), "text/plain"},
611*c2c66affSColin Finck     {data14, sizeof(data14), "text/plain"},
612*c2c66affSColin Finck     {data15, sizeof(data15), "text/plain"},
613*c2c66affSColin Finck     {data16, sizeof(data16), "image/pjpeg"},
614*c2c66affSColin Finck     {data17, sizeof(data17), "application/octet-stream", "image/pjpeg"},
615*c2c66affSColin Finck     {data18, sizeof(data18), "text/html", "image/pjpeg"},
616*c2c66affSColin Finck     {data19, sizeof(data19), "image/gif"},
617*c2c66affSColin Finck     {data20, sizeof(data20), "image/gif"},
618*c2c66affSColin Finck     {data21, sizeof(data21), "text/plain"},
619*c2c66affSColin Finck     {data22, sizeof(data22), "image/gif"},
620*c2c66affSColin Finck     {data23, sizeof(data23), "text/plain"},
621*c2c66affSColin Finck     {data24, sizeof(data24), "image/gif"},
622*c2c66affSColin Finck     {data25, sizeof(data25), "image/gif"},
623*c2c66affSColin Finck     {data26, sizeof(data26), "text/html", "image/gif"},
624*c2c66affSColin Finck     {data27, sizeof(data27), "text/plain"},
625*c2c66affSColin Finck     {data28, sizeof(data28), "image/bmp"},
626*c2c66affSColin Finck     {data29, sizeof(data29), "image/bmp"},
627*c2c66affSColin Finck     {data30, sizeof(data30), "application/octet-stream", "image/pjpeg"},
628*c2c66affSColin Finck     {data31, sizeof(data31), "text/html", "image/bmp"},
629*c2c66affSColin Finck     {data32, sizeof(data32), "application/octet-stream", "image/pjpeg"},
630*c2c66affSColin Finck     {data33, sizeof(data33), "application/octet-stream", "image/pjpeg"},
631*c2c66affSColin Finck     {data34, sizeof(data34), "image/x-png"},
632*c2c66affSColin Finck     {data35, sizeof(data35), "image/x-png"},
633*c2c66affSColin Finck     {data36, sizeof(data36), "application/octet-stream", "image/pjpeg"},
634*c2c66affSColin Finck     {data37, sizeof(data37), "text/html", "image/x-png"},
635*c2c66affSColin Finck     {data38, sizeof(data38), "application/octet-stream", "image/pjpeg"},
636*c2c66affSColin Finck     {data39, sizeof(data39), "image/tiff"},
637*c2c66affSColin Finck     {data40, sizeof(data40), "text/html", "image/tiff"},
638*c2c66affSColin Finck     {data41, sizeof(data41), "text/plain", NULL, "image/tiff"},
639*c2c66affSColin Finck     {data42, sizeof(data42), "text/plain"},
640*c2c66affSColin Finck     {data43, sizeof(data43), "application/octet-stream", "image/pjpeg"},
641*c2c66affSColin Finck     {data44, sizeof(data44), "video/avi"},
642*c2c66affSColin Finck     {data45, sizeof(data45), "text/plain"},
643*c2c66affSColin Finck     {data46, sizeof(data46), "text/plain"},
644*c2c66affSColin Finck     {data47, sizeof(data47), "text/plain"},
645*c2c66affSColin Finck     {data48, sizeof(data48), "text/html", "video/avi"},
646*c2c66affSColin Finck     {data49, sizeof(data49), "video/avi"},
647*c2c66affSColin Finck     {data50, sizeof(data50), "video/mpeg"},
648*c2c66affSColin Finck     {data51, sizeof(data51), "video/mpeg"},
649*c2c66affSColin Finck     {data52, sizeof(data52), "application/octet-stream", "image/pjpeg"},
650*c2c66affSColin Finck     {data53, sizeof(data53), "application/octet-stream", "image/pjpeg", "image/x-icon"},
651*c2c66affSColin Finck     {data54, sizeof(data54), "text/html", "video/mpeg"},
652*c2c66affSColin Finck     {data55, sizeof(data55), "application/x-gzip-compressed"},
653*c2c66affSColin Finck     {data56, sizeof(data56), "text/plain"},
654*c2c66affSColin Finck     {data57, sizeof(data57), "text/html", "application/x-gzip-compressed"},
655*c2c66affSColin Finck     {data58, sizeof(data58), "application/octet-stream", "image/pjpeg"},
656*c2c66affSColin Finck     {data59, sizeof(data59), "application/x-zip-compressed"},
657*c2c66affSColin Finck     {data60, sizeof(data60), "text/plain"},
658*c2c66affSColin Finck     {data61, sizeof(data61), "text/html", "application/x-zip-compressed"},
659*c2c66affSColin Finck     {data62, sizeof(data62), "application/java"},
660*c2c66affSColin Finck     {data63, sizeof(data63), "text/plain"},
661*c2c66affSColin Finck     {data64, sizeof(data64), "text/html", "application/java"},
662*c2c66affSColin Finck     {data65, sizeof(data65), "application/pdf"},
663*c2c66affSColin Finck     {data66, sizeof(data66), "text/plain"},
664*c2c66affSColin Finck     {data67, sizeof(data67), "text/html", "application/pdf"},
665*c2c66affSColin Finck     {data68, sizeof(data68), "application/x-msdownload"},
666*c2c66affSColin Finck     {data69, sizeof(data69), "text/plain"},
667*c2c66affSColin Finck     {data70, sizeof(data70), "text/html", "application/x-msdownload"},
668*c2c66affSColin Finck     {data71, sizeof(data71), "text/richtext"},
669*c2c66affSColin Finck     {data72, sizeof(data72), "text/plain"},
670*c2c66affSColin Finck     {data73, sizeof(data73), "text/plain"},
671*c2c66affSColin Finck     {data74, sizeof(data74), "text/html", "text/richtext"},
672*c2c66affSColin Finck     {data75, sizeof(data75), "audio/wav"},
673*c2c66affSColin Finck     {data76, sizeof(data76), "text/plain"},
674*c2c66affSColin Finck     {data77, sizeof(data77), "text/plain"},
675*c2c66affSColin Finck     {data78, sizeof(data78), "text/html", "text/plain"},
676*c2c66affSColin Finck     {data79, sizeof(data79), "application/postscript"},
677*c2c66affSColin Finck     {data80, sizeof(data80), "text/plain"},
678*c2c66affSColin Finck     {data81, sizeof(data81), "text/html", "application/postscript"},
679*c2c66affSColin Finck     {data82, sizeof(data82), "audio/basic"},
680*c2c66affSColin Finck     {data83, sizeof(data83), "text/plain"},
681*c2c66affSColin Finck     {data84, sizeof(data84), "text/html", "audio/basic"},
682*c2c66affSColin Finck     {data85, sizeof(data85), "text/plain"},
683*c2c66affSColin Finck     {data86, sizeof(data86), "image/tiff", NULL, "text/plain"},
684*c2c66affSColin Finck     {data87, sizeof(data87), "text/plain"},
685*c2c66affSColin Finck     {data88, sizeof(data88), "text/html", "text/plain"},
686*c2c66affSColin Finck     {data89, sizeof(data89), "text/html", "text/plain"},
687*c2c66affSColin Finck     {data90, sizeof(data90), "text/html", "text/plain"},
688*c2c66affSColin Finck     {data91, sizeof(data91), "text/xml", "text/plain"},
689*c2c66affSColin Finck     {data92, sizeof(data92), "text/xml", "text/plain"},
690*c2c66affSColin Finck     {data93, sizeof(data93), "text/xml", "text/plain"},
691*c2c66affSColin Finck     {data94, sizeof(data94), "text/html", "text/plain"},
692*c2c66affSColin Finck     {data95, sizeof(data95), "text/xml", "text/richtext"},
693*c2c66affSColin Finck     {data96, sizeof(data96), "text/plain"},
694*c2c66affSColin Finck     {data97, sizeof(data97), "text/html", "text/plain"},
695*c2c66affSColin Finck     {data98, sizeof(data98), "text/html", "text/plain"},
696*c2c66affSColin Finck     {data1, sizeof(data1), "text/plain", NULL, NULL, "res://mshtml.dll/blank.htm"},
697*c2c66affSColin Finck     {NULL, 0, "text/html", NULL, NULL, "res://mshtml.dll/blank.htm"},
698*c2c66affSColin Finck     {data1, sizeof(data1), "text/plain", NULL, NULL, "res://mshtml.dll/blank.htm", "application/octet-stream"},
699*c2c66affSColin Finck     {data1, sizeof(data1), "text/plain", NULL, NULL, "file:some%20file%2ejpg", "application/octet-stream"},
700*c2c66affSColin Finck     {NULL, sizeof(data1), "text/html", NULL, NULL, "res://mshtml.dll/blank.htm"},
701*c2c66affSColin Finck     {data1, sizeof(data1), "text/css", NULL, NULL, "http://www.winehq.org/test.css"},
702*c2c66affSColin Finck     {data2, sizeof(data2), "text/css", NULL, NULL, "http://www.winehq.org/test.css"},
703*c2c66affSColin Finck     {data10, sizeof(data10), "text/html", NULL, NULL, "http://www.winehq.org/test.css"},
704*c2c66affSColin Finck     {data1, sizeof(data1), "text/css", NULL, NULL, "http://www.winehq.org/test.css", "text/plain"},
705*c2c66affSColin Finck     {data1, sizeof(data1), "text/css", NULL, NULL, "http://www.winehq.org/test.css", "application/octet-stream"},
706*c2c66affSColin Finck     {data1, sizeof(data1), "text/test", NULL, NULL, "http://www.winehq.org/test.css", "text/test"}
707*c2c66affSColin Finck };
708*c2c66affSColin Finck 
709*c2c66affSColin Finck static void test_FindMimeFromData(void)
710*c2c66affSColin Finck {
711*c2c66affSColin Finck     WCHAR *mime, *proposed_mime, *url;
712*c2c66affSColin Finck     HRESULT hres;
713*c2c66affSColin Finck     BYTE b;
714*c2c66affSColin Finck     int i;
715*c2c66affSColin Finck 
716*c2c66affSColin Finck     static const WCHAR app_octet_streamW[] =
717*c2c66affSColin Finck         {'a','p','p','l','i','c','a','t','i','o','n','/','o','c','t','e','t','-','s','t','r','e','a','m',0};
718*c2c66affSColin Finck     static const WCHAR image_pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
719*c2c66affSColin Finck     static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
720*c2c66affSColin Finck     static const WCHAR text_plainW[] = {'t','e','x','t','/','p','l','a','i','n',0};
721*c2c66affSColin Finck 
722*c2c66affSColin Finck     for(i=0; i<sizeof(mime_tests)/sizeof(mime_tests[0]); i++) {
723*c2c66affSColin Finck         mime = (LPWSTR)0xf0f0f0f0;
724*c2c66affSColin Finck         url = a2w(mime_tests[i].url);
725*c2c66affSColin Finck         hres = pFindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0);
726*c2c66affSColin Finck         if(mime_tests[i].mime) {
727*c2c66affSColin Finck             ok(hres == S_OK || broken(mime_tests[i].broken_failure), "[%d] FindMimeFromData failed: %08x\n", i, hres);
728*c2c66affSColin Finck             if(hres == S_OK) {
729*c2c66affSColin Finck                 ok(!strcmp_wa(mime, mime_tests[i].mime)
730*c2c66affSColin Finck                    || broken(mime_tests[i].broken_mime && !strcmp_wa(mime, mime_tests[i].broken_mime)),
731*c2c66affSColin Finck                    "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
732*c2c66affSColin Finck                 CoTaskMemFree(mime);
733*c2c66affSColin Finck             }
734*c2c66affSColin Finck         }else {
735*c2c66affSColin Finck             ok(hres == E_FAIL || hres == mime_tests[i].hres,
736*c2c66affSColin Finck                "[%d] FindMimeFromData failed: %08x, expected %08x\n",
737*c2c66affSColin Finck                i, hres, mime_tests[i].hres);
738*c2c66affSColin Finck             ok(mime == (LPWSTR)0xf0f0f0f0, "[%d] mime != 0xf0f0f0f0\n", i);
739*c2c66affSColin Finck         }
740*c2c66affSColin Finck 
741*c2c66affSColin Finck         mime = (LPWSTR)0xf0f0f0f0;
742*c2c66affSColin Finck         hres = pFindMimeFromData(NULL, url, NULL, 0, text_plainW, 0, &mime, 0);
743*c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
744*c2c66affSColin Finck         ok(!strcmp_wa(mime, "text/plain"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
745*c2c66affSColin Finck         CoTaskMemFree(mime);
746*c2c66affSColin Finck 
747*c2c66affSColin Finck         mime = (LPWSTR)0xf0f0f0f0;
748*c2c66affSColin Finck         hres = pFindMimeFromData(NULL, url, NULL, 0, app_octet_streamW, 0, &mime, 0);
749*c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
750*c2c66affSColin Finck         ok(!strcmp_wa(mime, "application/octet-stream"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
751*c2c66affSColin Finck         CoTaskMemFree(mime);
752*c2c66affSColin Finck         heap_free(url);
753*c2c66affSColin Finck     }
754*c2c66affSColin Finck 
755*c2c66affSColin Finck     for(i=0; i < sizeof(mime_tests2)/sizeof(mime_tests2[0]); i++) {
756*c2c66affSColin Finck         url = a2w(mime_tests2[i].url);
757*c2c66affSColin Finck         proposed_mime = a2w(mime_tests2[i].proposed_mime);
758*c2c66affSColin Finck         hres = pFindMimeFromData(NULL, url, mime_tests2[i].data, mime_tests2[i].size,
759*c2c66affSColin Finck                 proposed_mime, 0, &mime, 0);
760*c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
761*c2c66affSColin Finck         b = !strcmp_wa(mime, mime_tests2[i].mime);
762*c2c66affSColin Finck         ok(b || broken(mime_tests2[i].broken_mime && !strcmp_wa(mime, mime_tests2[i].broken_mime)),
763*c2c66affSColin Finck             "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
764*c2c66affSColin Finck         heap_free(proposed_mime);
765*c2c66affSColin Finck         heap_free(url);
766*c2c66affSColin Finck         CoTaskMemFree(mime);
767*c2c66affSColin Finck         if(!b || url || proposed_mime)
768*c2c66affSColin Finck             continue;
769*c2c66affSColin Finck 
770*c2c66affSColin Finck         hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
771*c2c66affSColin Finck                 app_octet_streamW, 0, &mime, 0);
772*c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
773*c2c66affSColin Finck         ok(!strcmp_wa(mime, mime_tests2[i].mime) || broken(mime_tests2[i].broken_mime
774*c2c66affSColin Finck                         && !strcmp_wa(mime, mime_tests2[i].broken_mime)),
775*c2c66affSColin Finck                     "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
776*c2c66affSColin Finck         CoTaskMemFree(mime);
777*c2c66affSColin Finck 
778*c2c66affSColin Finck         hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
779*c2c66affSColin Finck                 text_plainW, 0, &mime, 0);
780*c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
781*c2c66affSColin Finck         ok(!strcmp_wa(mime, mime_tests2[i].mime) || broken(mime_tests2[i].broken_mime
782*c2c66affSColin Finck                     && !strcmp_wa(mime, mime_tests2[i].broken_mime)),
783*c2c66affSColin Finck                 "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
784*c2c66affSColin Finck         CoTaskMemFree(mime);
785*c2c66affSColin Finck 
786*c2c66affSColin Finck         hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
787*c2c66affSColin Finck                 text_htmlW, 0, &mime, 0);
788*c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
789*c2c66affSColin Finck         if(!strcmp("application/octet-stream", mime_tests2[i].mime)
790*c2c66affSColin Finck            || !strcmp("text/plain", mime_tests2[i].mime) || i==92)
791*c2c66affSColin Finck             ok(!strcmp_wa(mime, "text/html"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
792*c2c66affSColin Finck         else
793*c2c66affSColin Finck             ok(!strcmp_wa(mime, mime_tests2[i].mime), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
794*c2c66affSColin Finck         CoTaskMemFree(mime);
795*c2c66affSColin Finck 
796*c2c66affSColin Finck         hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
797*c2c66affSColin Finck                 image_pjpegW, 0, &mime, 0);
798*c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
799*c2c66affSColin Finck         ok(!strcmp_wa(mime, mime_tests2[i].mime_pjpeg ? mime_tests2[i].mime_pjpeg : mime_tests2[i].mime)
800*c2c66affSColin Finck            || broken(!strcmp_wa(mime, mime_tests2[i].mime)),
801*c2c66affSColin Finck            "[%d] wrong mime, got %s\n", i, wine_dbgstr_w(mime));
802*c2c66affSColin Finck         CoTaskMemFree(mime);
803*c2c66affSColin Finck     }
804*c2c66affSColin Finck 
805*c2c66affSColin Finck     hres = pFindMimeFromData(NULL, NULL, NULL, 0, NULL, 0, &mime, 0);
806*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
807*c2c66affSColin Finck 
808*c2c66affSColin Finck     hres = pFindMimeFromData(NULL, NULL, NULL, 0, text_plainW, 0, &mime, 0);
809*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
810*c2c66affSColin Finck 
811*c2c66affSColin Finck     hres = pFindMimeFromData(NULL, NULL, data1, 0, NULL, 0, &mime, 0);
812*c2c66affSColin Finck     ok(hres == E_FAIL, "FindMimeFromData failed: %08x, expected E_FAIL\n", hres);
813*c2c66affSColin Finck 
814*c2c66affSColin Finck     hres = pFindMimeFromData(NULL, url1, data1, 0, NULL, 0, &mime, 0);
815*c2c66affSColin Finck     ok(hres == E_FAIL, "FindMimeFromData failed: %08x, expected E_FAIL\n", hres);
816*c2c66affSColin Finck 
817*c2c66affSColin Finck     hres = pFindMimeFromData(NULL, NULL, data1, 0, text_plainW, 0, &mime, 0);
818*c2c66affSColin Finck     ok(hres == S_OK, "FindMimeFromData failed: %08x\n", hres);
819*c2c66affSColin Finck     ok(!strcmp_wa(mime, "text/plain"), "wrong mime: %s\n", wine_dbgstr_w(mime));
820*c2c66affSColin Finck     CoTaskMemFree(mime);
821*c2c66affSColin Finck 
822*c2c66affSColin Finck     hres = pFindMimeFromData(NULL, NULL, data1, 0, text_plainW, 0, NULL, 0);
823*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
824*c2c66affSColin Finck }
825*c2c66affSColin Finck 
826*c2c66affSColin Finck static void register_protocols(void)
827*c2c66affSColin Finck {
828*c2c66affSColin Finck     IInternetSession *session;
829*c2c66affSColin Finck     IClassFactory *factory;
830*c2c66affSColin Finck     HRESULT hres;
831*c2c66affSColin Finck 
832*c2c66affSColin Finck     static const WCHAR wszAbout[] = {'a','b','o','u','t',0};
833*c2c66affSColin Finck 
834*c2c66affSColin Finck     hres = pCoInternetGetSession(0, &session, 0);
835*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
836*c2c66affSColin Finck     if(FAILED(hres))
837*c2c66affSColin Finck         return;
838*c2c66affSColin Finck 
839*c2c66affSColin Finck     hres = CoGetClassObject(&CLSID_AboutProtocol, CLSCTX_INPROC_SERVER, NULL,
840*c2c66affSColin Finck             &IID_IClassFactory, (void**)&factory);
841*c2c66affSColin Finck     ok(hres == S_OK, "Could not get AboutProtocol factory: %08x\n", hres);
842*c2c66affSColin Finck     if(FAILED(hres))
843*c2c66affSColin Finck         return;
844*c2c66affSColin Finck 
845*c2c66affSColin Finck     IInternetSession_RegisterNameSpace(session, factory, &CLSID_AboutProtocol,
846*c2c66affSColin Finck                                        wszAbout, 0, NULL, 0);
847*c2c66affSColin Finck     IClassFactory_Release(factory);
848*c2c66affSColin Finck 
849*c2c66affSColin Finck     IInternetSession_Release(session);
850*c2c66affSColin Finck }
851*c2c66affSColin Finck 
852*c2c66affSColin Finck static HRESULT WINAPI InternetProtocolInfo_QueryInterface(IInternetProtocolInfo *iface,
853*c2c66affSColin Finck                                                           REFIID riid, void **ppv)
854*c2c66affSColin Finck {
855*c2c66affSColin Finck     ok(0, "unexpected call\n");
856*c2c66affSColin Finck     return E_NOINTERFACE;
857*c2c66affSColin Finck }
858*c2c66affSColin Finck 
859*c2c66affSColin Finck static ULONG WINAPI InternetProtocolInfo_AddRef(IInternetProtocolInfo *iface)
860*c2c66affSColin Finck {
861*c2c66affSColin Finck     return 2;
862*c2c66affSColin Finck }
863*c2c66affSColin Finck 
864*c2c66affSColin Finck static ULONG WINAPI InternetProtocolInfo_Release(IInternetProtocolInfo *iface)
865*c2c66affSColin Finck {
866*c2c66affSColin Finck     return 1;
867*c2c66affSColin Finck }
868*c2c66affSColin Finck 
869*c2c66affSColin Finck static HRESULT WINAPI InternetProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
870*c2c66affSColin Finck         PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
871*c2c66affSColin Finck         DWORD *pcchResult, DWORD dwReserved)
872*c2c66affSColin Finck {
873*c2c66affSColin Finck     CHECK_EXPECT2(ParseUrl);
874*c2c66affSColin Finck 
875*c2c66affSColin Finck     if(ParseAction == PARSE_SECURITY_URL) {
876*c2c66affSColin Finck         if(pcchResult)
877*c2c66affSColin Finck             *pcchResult = sizeof(url1)/sizeof(WCHAR);
878*c2c66affSColin Finck 
879*c2c66affSColin Finck         if(cchResult<sizeof(url1)/sizeof(WCHAR))
880*c2c66affSColin Finck             return S_FALSE;
881*c2c66affSColin Finck 
882*c2c66affSColin Finck         memcpy(pwzResult, url1, sizeof(url1));
883*c2c66affSColin Finck         return S_OK;
884*c2c66affSColin Finck     }
885*c2c66affSColin Finck 
886*c2c66affSColin Finck     return E_NOTIMPL;
887*c2c66affSColin Finck }
888*c2c66affSColin Finck 
889*c2c66affSColin Finck static HRESULT WINAPI InternetProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
890*c2c66affSColin Finck         LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
891*c2c66affSColin Finck         LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
892*c2c66affSColin Finck {
893*c2c66affSColin Finck     ok(0, "unexpected call\n");
894*c2c66affSColin Finck     return E_NOTIMPL;
895*c2c66affSColin Finck }
896*c2c66affSColin Finck 
897*c2c66affSColin Finck static HRESULT WINAPI InternetProtocolInfo_CompareUrl(IInternetProtocolInfo *iface,
898*c2c66affSColin Finck         LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
899*c2c66affSColin Finck {
900*c2c66affSColin Finck     ok(0, "unexpected call\n");
901*c2c66affSColin Finck     return E_NOTIMPL;
902*c2c66affSColin Finck }
903*c2c66affSColin Finck 
904*c2c66affSColin Finck static HRESULT WINAPI InternetProtocolInfo_QueryInfo(IInternetProtocolInfo *iface,
905*c2c66affSColin Finck         LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer,
906*c2c66affSColin Finck         DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
907*c2c66affSColin Finck {
908*c2c66affSColin Finck     ok(0, "unexpected call\n");
909*c2c66affSColin Finck     return E_NOTIMPL;
910*c2c66affSColin Finck }
911*c2c66affSColin Finck 
912*c2c66affSColin Finck static const IInternetProtocolInfoVtbl InternetProtocolInfoVtbl = {
913*c2c66affSColin Finck     InternetProtocolInfo_QueryInterface,
914*c2c66affSColin Finck     InternetProtocolInfo_AddRef,
915*c2c66affSColin Finck     InternetProtocolInfo_Release,
916*c2c66affSColin Finck     InternetProtocolInfo_ParseUrl,
917*c2c66affSColin Finck     InternetProtocolInfo_CombineUrl,
918*c2c66affSColin Finck     InternetProtocolInfo_CompareUrl,
919*c2c66affSColin Finck     InternetProtocolInfo_QueryInfo
920*c2c66affSColin Finck };
921*c2c66affSColin Finck 
922*c2c66affSColin Finck static IInternetProtocolInfo protocol_info = { &InternetProtocolInfoVtbl };
923*c2c66affSColin Finck 
924*c2c66affSColin Finck static HRESULT qiret;
925*c2c66affSColin Finck static IClassFactory *expect_cf;
926*c2c66affSColin Finck 
927*c2c66affSColin Finck static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
928*c2c66affSColin Finck {
929*c2c66affSColin Finck     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
930*c2c66affSColin Finck         CHECK_EXPECT2(QI_IInternetProtocolInfo);
931*c2c66affSColin Finck         ok(iface == expect_cf, "unexpected iface\n");
932*c2c66affSColin Finck         *ppv = &protocol_info;
933*c2c66affSColin Finck         return qiret;
934*c2c66affSColin Finck     }
935*c2c66affSColin Finck 
936*c2c66affSColin Finck     ok(0, "unexpected call\n");
937*c2c66affSColin Finck     return E_NOINTERFACE;
938*c2c66affSColin Finck }
939*c2c66affSColin Finck 
940*c2c66affSColin Finck static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
941*c2c66affSColin Finck {
942*c2c66affSColin Finck     return 2;
943*c2c66affSColin Finck }
944*c2c66affSColin Finck 
945*c2c66affSColin Finck static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
946*c2c66affSColin Finck {
947*c2c66affSColin Finck     return 1;
948*c2c66affSColin Finck }
949*c2c66affSColin Finck 
950*c2c66affSColin Finck static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
951*c2c66affSColin Finck                                         REFIID riid, void **ppv)
952*c2c66affSColin Finck {
953*c2c66affSColin Finck     ok(0, "unexpected call\n");
954*c2c66affSColin Finck     return E_NOTIMPL;
955*c2c66affSColin Finck }
956*c2c66affSColin Finck 
957*c2c66affSColin Finck static HRESULT WINAPI ProtocolCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
958*c2c66affSColin Finck                                         REFIID riid, void **ppv)
959*c2c66affSColin Finck {
960*c2c66affSColin Finck     CHECK_EXPECT(CreateInstance);
961*c2c66affSColin Finck 
962*c2c66affSColin Finck     ok(iface == expect_cf, "unexpected iface\n");
963*c2c66affSColin Finck     ok(pOuter == NULL, "pOuter = %p\n", pOuter);
964*c2c66affSColin Finck     ok(IsEqualGUID(&IID_IInternetProtocolInfo, riid), "unexpected riid\n");
965*c2c66affSColin Finck     ok(ppv != NULL, "ppv == NULL\n");
966*c2c66affSColin Finck 
967*c2c66affSColin Finck     *ppv = &protocol_info;
968*c2c66affSColin Finck     return S_OK;
969*c2c66affSColin Finck }
970*c2c66affSColin Finck 
971*c2c66affSColin Finck static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
972*c2c66affSColin Finck {
973*c2c66affSColin Finck     ok(0, "unexpected call\n");
974*c2c66affSColin Finck     return S_OK;
975*c2c66affSColin Finck }
976*c2c66affSColin Finck 
977*c2c66affSColin Finck static const IClassFactoryVtbl ClassFactoryVtbl = {
978*c2c66affSColin Finck     ClassFactory_QueryInterface,
979*c2c66affSColin Finck     ClassFactory_AddRef,
980*c2c66affSColin Finck     ClassFactory_Release,
981*c2c66affSColin Finck     ClassFactory_CreateInstance,
982*c2c66affSColin Finck     ClassFactory_LockServer
983*c2c66affSColin Finck };
984*c2c66affSColin Finck 
985*c2c66affSColin Finck static const IClassFactoryVtbl ProtocolCFVtbl = {
986*c2c66affSColin Finck     ClassFactory_QueryInterface,
987*c2c66affSColin Finck     ClassFactory_AddRef,
988*c2c66affSColin Finck     ClassFactory_Release,
989*c2c66affSColin Finck     ProtocolCF_CreateInstance,
990*c2c66affSColin Finck     ClassFactory_LockServer
991*c2c66affSColin Finck };
992*c2c66affSColin Finck 
993*c2c66affSColin Finck static IClassFactory test_protocol_cf = { &ProtocolCFVtbl };
994*c2c66affSColin Finck static IClassFactory test_protocol_cf2 = { &ProtocolCFVtbl };
995*c2c66affSColin Finck static IClassFactory test_cf = { &ClassFactoryVtbl };
996*c2c66affSColin Finck 
997*c2c66affSColin Finck static void test_NameSpace(void)
998*c2c66affSColin Finck {
999*c2c66affSColin Finck     IInternetSession *session;
1000*c2c66affSColin Finck     WCHAR buf[200];
1001*c2c66affSColin Finck     LPWSTR sec_url;
1002*c2c66affSColin Finck     DWORD size;
1003*c2c66affSColin Finck     HRESULT hres;
1004*c2c66affSColin Finck 
1005*c2c66affSColin Finck     static const WCHAR wszTest[] = {'t','e','s','t',0};
1006*c2c66affSColin Finck 
1007*c2c66affSColin Finck     hres = pCoInternetGetSession(0, &session, 0);
1008*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
1009*c2c66affSColin Finck     if(FAILED(hres))
1010*c2c66affSColin Finck         return;
1011*c2c66affSColin Finck 
1012*c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, NULL, &IID_NULL,
1013*c2c66affSColin Finck                                               wszTest, 0, NULL, 0);
1014*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "RegisterNameSpace failed: %08x\n", hres);
1015*c2c66affSColin Finck 
1016*c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1017*c2c66affSColin Finck                                               NULL, 0, NULL, 0);
1018*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "RegisterNameSpace failed: %08x\n", hres);
1019*c2c66affSColin Finck 
1020*c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1021*c2c66affSColin Finck                                               wszTest, 0, NULL, 0);
1022*c2c66affSColin Finck     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1023*c2c66affSColin Finck 
1024*c2c66affSColin Finck     qiret = E_NOINTERFACE;
1025*c2c66affSColin Finck     expect_cf = &test_protocol_cf;
1026*c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1027*c2c66affSColin Finck     SET_EXPECT(CreateInstance);
1028*c2c66affSColin Finck     SET_EXPECT(ParseUrl);
1029*c2c66affSColin Finck 
1030*c2c66affSColin Finck     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, sizeof(buf)/sizeof(WCHAR),
1031*c2c66affSColin Finck                               &size, 0);
1032*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1033*c2c66affSColin Finck 
1034*c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1035*c2c66affSColin Finck     CHECK_CALLED(CreateInstance);
1036*c2c66affSColin Finck     CHECK_CALLED(ParseUrl);
1037*c2c66affSColin Finck 
1038*c2c66affSColin Finck     qiret = S_OK;
1039*c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1040*c2c66affSColin Finck     SET_EXPECT(ParseUrl);
1041*c2c66affSColin Finck 
1042*c2c66affSColin Finck     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, sizeof(buf)/sizeof(WCHAR),
1043*c2c66affSColin Finck                               &size, 0);
1044*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1045*c2c66affSColin Finck 
1046*c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1047*c2c66affSColin Finck     CHECK_CALLED(ParseUrl);
1048*c2c66affSColin Finck 
1049*c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1050*c2c66affSColin Finck     SET_EXPECT(ParseUrl);
1051*c2c66affSColin Finck 
1052*c2c66affSColin Finck     hres = pCoInternetParseUrl(url8, PARSE_SECURITY_URL, 0, buf,
1053*c2c66affSColin Finck             sizeof(buf)/sizeof(WCHAR), &size, 0);
1054*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1055*c2c66affSColin Finck     ok(size == sizeof(url1)/sizeof(WCHAR), "Size = %d\n", size);
1056*c2c66affSColin Finck     if(size == sizeof(url1)/sizeof(WCHAR))
1057*c2c66affSColin Finck         ok(!memcmp(buf, url1, sizeof(url1)), "Encoded url = %s\n", wine_dbgstr_w(buf));
1058*c2c66affSColin Finck 
1059*c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1060*c2c66affSColin Finck     CHECK_CALLED(ParseUrl);
1061*c2c66affSColin Finck 
1062*c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1063*c2c66affSColin Finck     SET_EXPECT(ParseUrl);
1064*c2c66affSColin Finck 
1065*c2c66affSColin Finck     if (pCoInternetGetSecurityUrl) {
1066*c2c66affSColin Finck         hres = pCoInternetGetSecurityUrl(url8, &sec_url, PSU_SECURITY_URL_ONLY, 0);
1067*c2c66affSColin Finck         ok(hres == S_OK, "CoInternetGetSecurityUrl failed: %08x\n", hres);
1068*c2c66affSColin Finck         if(hres == S_OK) {
1069*c2c66affSColin Finck             ok(lstrlenW(sec_url)>sizeof(wszFile)/sizeof(WCHAR) &&
1070*c2c66affSColin Finck                     !memcmp(sec_url, wszFile, sizeof(wszFile)-sizeof(WCHAR)),
1071*c2c66affSColin Finck                     "Encoded url = %s\n", wine_dbgstr_w(sec_url));
1072*c2c66affSColin Finck             CoTaskMemFree(sec_url);
1073*c2c66affSColin Finck         }
1074*c2c66affSColin Finck 
1075*c2c66affSColin Finck         CHECK_CALLED(QI_IInternetProtocolInfo);
1076*c2c66affSColin Finck         CHECK_CALLED(ParseUrl);
1077*c2c66affSColin Finck     }
1078*c2c66affSColin Finck 
1079*c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1080*c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1081*c2c66affSColin Finck 
1082*c2c66affSColin Finck     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, sizeof(buf)/sizeof(WCHAR),
1083*c2c66affSColin Finck                               &size, 0);
1084*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1085*c2c66affSColin Finck 
1086*c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf2, &IID_NULL,
1087*c2c66affSColin Finck                                               wszTest, 0, NULL, 0);
1088*c2c66affSColin Finck     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1089*c2c66affSColin Finck 
1090*c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1091*c2c66affSColin Finck                                               wszTest, 0, NULL, 0);
1092*c2c66affSColin Finck     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1093*c2c66affSColin Finck 
1094*c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1095*c2c66affSColin Finck                                               wszTest, 0, NULL, 0);
1096*c2c66affSColin Finck     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1097*c2c66affSColin Finck 
1098*c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1099*c2c66affSColin Finck     SET_EXPECT(ParseUrl);
1100*c2c66affSColin Finck 
1101*c2c66affSColin Finck     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, sizeof(buf)/sizeof(WCHAR),
1102*c2c66affSColin Finck                               &size, 0);
1103*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1104*c2c66affSColin Finck 
1105*c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1106*c2c66affSColin Finck     CHECK_CALLED(ParseUrl);
1107*c2c66affSColin Finck 
1108*c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1109*c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1110*c2c66affSColin Finck 
1111*c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1112*c2c66affSColin Finck     SET_EXPECT(ParseUrl);
1113*c2c66affSColin Finck 
1114*c2c66affSColin Finck     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, sizeof(buf)/sizeof(WCHAR),
1115*c2c66affSColin Finck                               &size, 0);
1116*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1117*c2c66affSColin Finck 
1118*c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1119*c2c66affSColin Finck     CHECK_CALLED(ParseUrl);
1120*c2c66affSColin Finck 
1121*c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1122*c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1123*c2c66affSColin Finck 
1124*c2c66affSColin Finck     expect_cf = &test_protocol_cf2;
1125*c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1126*c2c66affSColin Finck     SET_EXPECT(ParseUrl);
1127*c2c66affSColin Finck 
1128*c2c66affSColin Finck     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, sizeof(buf)/sizeof(WCHAR),
1129*c2c66affSColin Finck                               &size, 0);
1130*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1131*c2c66affSColin Finck 
1132*c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1133*c2c66affSColin Finck     CHECK_CALLED(ParseUrl);
1134*c2c66affSColin Finck 
1135*c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1136*c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1137*c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1138*c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1139*c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, NULL);
1140*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UnregisterNameSpace failed: %08x\n", hres);
1141*c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, NULL, wszTest);
1142*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UnregisterNameSpace failed: %08x\n", hres);
1143*c2c66affSColin Finck 
1144*c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf2, wszTest);
1145*c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1146*c2c66affSColin Finck 
1147*c2c66affSColin Finck     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, sizeof(buf)/sizeof(WCHAR),
1148*c2c66affSColin Finck                               &size, 0);
1149*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1150*c2c66affSColin Finck 
1151*c2c66affSColin Finck     IInternetSession_Release(session);
1152*c2c66affSColin Finck }
1153*c2c66affSColin Finck 
1154*c2c66affSColin Finck static void test_MimeFilter(void)
1155*c2c66affSColin Finck {
1156*c2c66affSColin Finck     IInternetSession *session;
1157*c2c66affSColin Finck     HRESULT hres;
1158*c2c66affSColin Finck 
1159*c2c66affSColin Finck     static const WCHAR mimeW[] = {'t','e','s','t','/','m','i','m','e',0};
1160*c2c66affSColin Finck 
1161*c2c66affSColin Finck     hres = pCoInternetGetSession(0, &session, 0);
1162*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
1163*c2c66affSColin Finck     if(FAILED(hres))
1164*c2c66affSColin Finck         return;
1165*c2c66affSColin Finck 
1166*c2c66affSColin Finck     hres = IInternetSession_RegisterMimeFilter(session, &test_cf, &IID_NULL, mimeW);
1167*c2c66affSColin Finck     ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
1168*c2c66affSColin Finck 
1169*c2c66affSColin Finck     hres = IInternetSession_UnregisterMimeFilter(session, &test_cf, mimeW);
1170*c2c66affSColin Finck     ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1171*c2c66affSColin Finck 
1172*c2c66affSColin Finck     hres = IInternetSession_UnregisterMimeFilter(session, &test_cf, mimeW);
1173*c2c66affSColin Finck     ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1174*c2c66affSColin Finck 
1175*c2c66affSColin Finck     hres = IInternetSession_UnregisterMimeFilter(session, (void*)0xdeadbeef, mimeW);
1176*c2c66affSColin Finck     ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1177*c2c66affSColin Finck 
1178*c2c66affSColin Finck     IInternetSession_Release(session);
1179*c2c66affSColin Finck }
1180*c2c66affSColin Finck 
1181*c2c66affSColin Finck static ULONG WINAPI unk_Release(IUnknown *iface)
1182*c2c66affSColin Finck {
1183*c2c66affSColin Finck     CHECK_EXPECT(unk_Release);
1184*c2c66affSColin Finck     return 0;
1185*c2c66affSColin Finck }
1186*c2c66affSColin Finck 
1187*c2c66affSColin Finck static const IUnknownVtbl unk_vtbl = {
1188*c2c66affSColin Finck     (void*)0xdeadbeef,
1189*c2c66affSColin Finck     (void*)0xdeadbeef,
1190*c2c66affSColin Finck     unk_Release
1191*c2c66affSColin Finck };
1192*c2c66affSColin Finck 
1193*c2c66affSColin Finck static void test_ReleaseBindInfo(void)
1194*c2c66affSColin Finck {
1195*c2c66affSColin Finck     BINDINFO bi;
1196*c2c66affSColin Finck     IUnknown unk = { &unk_vtbl };
1197*c2c66affSColin Finck 
1198*c2c66affSColin Finck     pReleaseBindInfo(NULL); /* shouldn't crash */
1199*c2c66affSColin Finck 
1200*c2c66affSColin Finck     memset(&bi, 0, sizeof(bi));
1201*c2c66affSColin Finck     bi.cbSize = sizeof(BINDINFO);
1202*c2c66affSColin Finck     bi.pUnk = &unk;
1203*c2c66affSColin Finck     SET_EXPECT(unk_Release);
1204*c2c66affSColin Finck     pReleaseBindInfo(&bi);
1205*c2c66affSColin Finck     ok(bi.cbSize == sizeof(BINDINFO), "bi.cbSize=%d\n", bi.cbSize);
1206*c2c66affSColin Finck     ok(bi.pUnk == NULL, "bi.pUnk=%p, expected NULL\n", bi.pUnk);
1207*c2c66affSColin Finck     CHECK_CALLED(unk_Release);
1208*c2c66affSColin Finck 
1209*c2c66affSColin Finck     memset(&bi, 0, sizeof(bi));
1210*c2c66affSColin Finck     bi.cbSize = offsetof(BINDINFO, pUnk);
1211*c2c66affSColin Finck     bi.pUnk = &unk;
1212*c2c66affSColin Finck     pReleaseBindInfo(&bi);
1213*c2c66affSColin Finck     ok(bi.cbSize == offsetof(BINDINFO, pUnk), "bi.cbSize=%d\n", bi.cbSize);
1214*c2c66affSColin Finck     ok(bi.pUnk == &unk, "bi.pUnk=%p, expected %p\n", bi.pUnk, &unk);
1215*c2c66affSColin Finck 
1216*c2c66affSColin Finck     memset(&bi, 0, sizeof(bi));
1217*c2c66affSColin Finck     bi.pUnk = &unk;
1218*c2c66affSColin Finck     pReleaseBindInfo(&bi);
1219*c2c66affSColin Finck     ok(!bi.cbSize, "bi.cbSize=%d, expected 0\n", bi.cbSize);
1220*c2c66affSColin Finck     ok(bi.pUnk == &unk, "bi.pUnk=%p, expected %p\n", bi.pUnk, &unk);
1221*c2c66affSColin Finck }
1222*c2c66affSColin Finck 
1223*c2c66affSColin Finck static void test_CopyStgMedium(void)
1224*c2c66affSColin Finck {
1225*c2c66affSColin Finck     STGMEDIUM src, dst;
1226*c2c66affSColin Finck     HGLOBAL empty, hg;
1227*c2c66affSColin Finck     char *ptr1, *ptr2;
1228*c2c66affSColin Finck     HRESULT hres;
1229*c2c66affSColin Finck     int size;
1230*c2c66affSColin Finck 
1231*c2c66affSColin Finck     static WCHAR fileW[] = {'f','i','l','e',0};
1232*c2c66affSColin Finck 
1233*c2c66affSColin Finck     memset(&src, 0xf0, sizeof(src));
1234*c2c66affSColin Finck     memset(&dst, 0xe0, sizeof(dst));
1235*c2c66affSColin Finck     memset(&empty, 0xf0, sizeof(empty));
1236*c2c66affSColin Finck     src.tymed = TYMED_NULL;
1237*c2c66affSColin Finck     src.pUnkForRelease = NULL;
1238*c2c66affSColin Finck     hres = pCopyStgMedium(&src, &dst);
1239*c2c66affSColin Finck     ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1240*c2c66affSColin Finck     ok(dst.tymed == TYMED_NULL, "tymed=%d\n", dst.tymed);
1241*c2c66affSColin Finck     ok(dst.u.hGlobal == empty, "u=%p\n", dst.u.hGlobal);
1242*c2c66affSColin Finck     ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1243*c2c66affSColin Finck 
1244*c2c66affSColin Finck     memset(&dst, 0xe0, sizeof(dst));
1245*c2c66affSColin Finck     src.tymed = TYMED_ISTREAM;
1246*c2c66affSColin Finck     src.u.pstm = NULL;
1247*c2c66affSColin Finck     src.pUnkForRelease = NULL;
1248*c2c66affSColin Finck     hres = pCopyStgMedium(&src, &dst);
1249*c2c66affSColin Finck     ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1250*c2c66affSColin Finck     ok(dst.tymed == TYMED_ISTREAM, "tymed=%d\n", dst.tymed);
1251*c2c66affSColin Finck     ok(!dst.u.pstm, "pstm=%p\n", dst.u.pstm);
1252*c2c66affSColin Finck     ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1253*c2c66affSColin Finck 
1254*c2c66affSColin Finck     memset(&dst, 0xe0, sizeof(dst));
1255*c2c66affSColin Finck     src.tymed = TYMED_FILE;
1256*c2c66affSColin Finck     src.u.lpszFileName = fileW;
1257*c2c66affSColin Finck     src.pUnkForRelease = NULL;
1258*c2c66affSColin Finck     hres = pCopyStgMedium(&src, &dst);
1259*c2c66affSColin Finck     ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1260*c2c66affSColin Finck     ok(dst.tymed == TYMED_FILE, "tymed=%d\n", dst.tymed);
1261*c2c66affSColin Finck     ok(dst.u.lpszFileName && dst.u.lpszFileName != fileW, "lpszFileName=%p\n", dst.u.lpszFileName);
1262*c2c66affSColin Finck     ok(!lstrcmpW(dst.u.lpszFileName, fileW), "wrong file name\n");
1263*c2c66affSColin Finck     ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1264*c2c66affSColin Finck     ReleaseStgMedium(&dst);
1265*c2c66affSColin Finck 
1266*c2c66affSColin Finck     /* TYMED_HGLOBAL */
1267*c2c66affSColin Finck     hg = GlobalAlloc(GMEM_MOVEABLE, 10);
1268*c2c66affSColin Finck     ptr1 = GlobalLock(hg);
1269*c2c66affSColin Finck     memset(ptr1, 0xfa, 10);
1270*c2c66affSColin Finck     memset(&dst, 0xe0, sizeof(dst));
1271*c2c66affSColin Finck     src.tymed = TYMED_HGLOBAL;
1272*c2c66affSColin Finck     src.u.hGlobal = hg;
1273*c2c66affSColin Finck     hres = pCopyStgMedium(&src, &dst);
1274*c2c66affSColin Finck     ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1275*c2c66affSColin Finck     ok(dst.tymed == TYMED_HGLOBAL, "tymed=%d\n", dst.tymed);
1276*c2c66affSColin Finck     ok(dst.u.hGlobal != hg, "got %p, %p\n", dst.u.hGlobal, hg);
1277*c2c66affSColin Finck     size = GlobalSize(dst.u.hGlobal);
1278*c2c66affSColin Finck     ok(size == 10, "got size %d\n", size);
1279*c2c66affSColin Finck     /* compare contents */
1280*c2c66affSColin Finck     ptr2 = GlobalLock(dst.u.hGlobal);
1281*c2c66affSColin Finck     ok(!memcmp(ptr1, ptr2, 10), "got wrong data\n");
1282*c2c66affSColin Finck     GlobalUnlock(ptr2);
1283*c2c66affSColin Finck     GlobalUnlock(ptr1);
1284*c2c66affSColin Finck     ok(GlobalFlags(dst.u.hGlobal) == 0, "got 0x%08x\n", GlobalFlags(dst.u.hGlobal));
1285*c2c66affSColin Finck     GlobalFree(hg);
1286*c2c66affSColin Finck     ReleaseStgMedium(&dst);
1287*c2c66affSColin Finck 
1288*c2c66affSColin Finck     memset(&dst, 0xe0, sizeof(dst));
1289*c2c66affSColin Finck     src.tymed = TYMED_HGLOBAL;
1290*c2c66affSColin Finck     src.u.hGlobal = NULL;
1291*c2c66affSColin Finck     hres = pCopyStgMedium(&src, &dst);
1292*c2c66affSColin Finck     ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1293*c2c66affSColin Finck     ok(dst.u.hGlobal == NULL, "got %p\n", dst.u.hGlobal);
1294*c2c66affSColin Finck 
1295*c2c66affSColin Finck     hres = pCopyStgMedium(&src, NULL);
1296*c2c66affSColin Finck     ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
1297*c2c66affSColin Finck     hres = pCopyStgMedium(NULL, &dst);
1298*c2c66affSColin Finck     ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
1299*c2c66affSColin Finck }
1300*c2c66affSColin Finck 
1301*c2c66affSColin Finck static void test_CopyBindInfo(void)
1302*c2c66affSColin Finck {
1303*c2c66affSColin Finck     BINDINFO src[2], dest[2];
1304*c2c66affSColin Finck     SECURITY_DESCRIPTOR sec_desc;
1305*c2c66affSColin Finck     HRESULT hres;
1306*c2c66affSColin Finck     int i;
1307*c2c66affSColin Finck 
1308*c2c66affSColin Finck     hres = pCopyBindInfo(NULL, NULL);
1309*c2c66affSColin Finck     ok(hres == E_POINTER, "CopyBindInfo returned %08x, expected E_POINTER\n", hres);
1310*c2c66affSColin Finck 
1311*c2c66affSColin Finck     memset(src, 0, sizeof(BINDINFO[2]));
1312*c2c66affSColin Finck     memset(dest, 0xde, sizeof(BINDINFO[2]));
1313*c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1314*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "CopyBindInfo returned: %08x, expected E_INVALIDARG\n", hres);
1315*c2c66affSColin Finck 
1316*c2c66affSColin Finck     memset(src, 0, sizeof(BINDINFO[2]));
1317*c2c66affSColin Finck     memset(dest, 0xde, sizeof(BINDINFO[2]));
1318*c2c66affSColin Finck     src[0].cbSize = sizeof(BINDINFO);
1319*c2c66affSColin Finck     dest[0].cbSize = 0;
1320*c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1321*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "CopyBindInfo returned: %08x, expected E_INVALIDARG\n", hres);
1322*c2c66affSColin Finck 
1323*c2c66affSColin Finck     memset(src, 0, sizeof(BINDINFO[2]));
1324*c2c66affSColin Finck     memset(dest, 0xde, sizeof(BINDINFO[2]));
1325*c2c66affSColin Finck     src[0].cbSize = 1;
1326*c2c66affSColin Finck     dest[0].cbSize = sizeof(BINDINFO)+sizeof(DWORD);
1327*c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1328*c2c66affSColin Finck     ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1329*c2c66affSColin Finck     ok(dest[0].cbSize == sizeof(BINDINFO)+sizeof(DWORD), "incorrect cbSize: %d\n", dest[0].cbSize);
1330*c2c66affSColin Finck     for(i=1; i<dest[0].cbSize/sizeof(int); i++)
1331*c2c66affSColin Finck         ok(((int*)dest)[i] == 0, "unset values should be set to 0, got %d on %d\n", ((int*)dest)[i], i);
1332*c2c66affSColin Finck 
1333*c2c66affSColin Finck     memset(src, 0, sizeof(BINDINFO[2]));
1334*c2c66affSColin Finck     memset(dest, 0xde, sizeof(BINDINFO[2]));
1335*c2c66affSColin Finck     src[0].cbSize = sizeof(BINDINFO)+2*sizeof(DWORD);
1336*c2c66affSColin Finck     dest[0].cbSize = sizeof(BINDINFO)+sizeof(DWORD);
1337*c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1338*c2c66affSColin Finck     ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1339*c2c66affSColin Finck     ok(dest[1].cbSize == src[1].cbSize, "additional data should be copied\n");
1340*c2c66affSColin Finck     ok(dest[1].szExtraInfo != src[1].szExtraInfo,
1341*c2c66affSColin Finck             "data not fitting in destination buffer should not be copied\n");
1342*c2c66affSColin Finck 
1343*c2c66affSColin Finck     memset(src, 0xf0, sizeof(BINDINFO[2]));
1344*c2c66affSColin Finck     memset(dest, 0xde, sizeof(BINDINFO[2]));
1345*c2c66affSColin Finck     src[0].cbSize = sizeof(BINDINFO);
1346*c2c66affSColin Finck     src[0].szExtraInfo = CoTaskMemAlloc(sizeof(WCHAR));
1347*c2c66affSColin Finck     src[0].szExtraInfo[0] = 0;
1348*c2c66affSColin Finck     src[0].szCustomVerb = NULL;
1349*c2c66affSColin Finck     src[0].pUnk = NULL;
1350*c2c66affSColin Finck     src[0].stgmedData.tymed = TYMED_NULL;
1351*c2c66affSColin Finck     src[0].stgmedData.pUnkForRelease = NULL;
1352*c2c66affSColin Finck     dest[0].cbSize = sizeof(BINDINFO);
1353*c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1354*c2c66affSColin Finck     ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1355*c2c66affSColin Finck 
1356*c2c66affSColin Finck     ok(dest[0].cbSize == sizeof(BINDINFO), "incorrect cbSize: %d\n", dest[0].cbSize);
1357*c2c66affSColin Finck     ok(dest[0].szExtraInfo && !dest[0].szExtraInfo[0] && dest[0].szExtraInfo!=src[0].szExtraInfo,
1358*c2c66affSColin Finck             "incorrect szExtraInfo: (%p!=%p) %d\n", dest[0].szExtraInfo,
1359*c2c66affSColin Finck             src[0].szExtraInfo, dest[0].szExtraInfo[0]);
1360*c2c66affSColin Finck     ok(!memcmp(&dest[0].stgmedData, &src[0].stgmedData, sizeof(STGMEDIUM)),
1361*c2c66affSColin Finck             "incorrect stgmedData value\n");
1362*c2c66affSColin Finck     ok(src[0].grfBindInfoF == dest[0].grfBindInfoF, "grfBindInfoF = %x, expected %x\n",
1363*c2c66affSColin Finck             dest[0].grfBindInfoF, src[0].grfBindInfoF);
1364*c2c66affSColin Finck     ok(src[0].dwBindVerb == dest[0].dwBindVerb, "dwBindVerb = %x, expected %x\n",
1365*c2c66affSColin Finck             dest[0].dwBindVerb, src[0].dwBindVerb);
1366*c2c66affSColin Finck     ok(!dest[0].szCustomVerb, "szCustmoVerb != NULL\n");
1367*c2c66affSColin Finck     ok(src[0].cbstgmedData == dest[0].cbstgmedData, "cbstgmedData = %x, expected %x\n",
1368*c2c66affSColin Finck             dest[0].cbstgmedData, src[0].cbstgmedData);
1369*c2c66affSColin Finck     ok(src[0].dwOptions == dest[0].dwOptions, "dwOptions = %x, expected %x\n",
1370*c2c66affSColin Finck             dest[0].dwOptions, src[0].dwOptions);
1371*c2c66affSColin Finck     ok(src[0].dwOptionsFlags == dest[0].dwOptionsFlags, "dwOptionsFlags = %x, expected %x\n",
1372*c2c66affSColin Finck             dest[0].dwOptionsFlags, src[0].dwOptionsFlags);
1373*c2c66affSColin Finck     ok(src[0].dwCodePage == dest[0].dwCodePage, "dwCodePage = %x, expected %x\n",
1374*c2c66affSColin Finck             dest[0].dwCodePage, src[0].dwCodePage);
1375*c2c66affSColin Finck     ok(!dest[0].securityAttributes.nLength,
1376*c2c66affSColin Finck             "unexpected securityAttributes.nLength value: %d\n",
1377*c2c66affSColin Finck             dest[0].securityAttributes.nLength);
1378*c2c66affSColin Finck     ok(!dest[0].securityAttributes.lpSecurityDescriptor,
1379*c2c66affSColin Finck             "unexpected securityAttributes.lpSecurityDescriptor value: %p\n",
1380*c2c66affSColin Finck             dest[0].securityAttributes.lpSecurityDescriptor);
1381*c2c66affSColin Finck     ok(!dest[0].securityAttributes.bInheritHandle,
1382*c2c66affSColin Finck             "unexpected securityAttributes.bInheritHandle value: %d\n",
1383*c2c66affSColin Finck             dest[0].securityAttributes.bInheritHandle);
1384*c2c66affSColin Finck     ok(!memcmp(&dest[0].iid, &src[0].iid, sizeof(IID)),
1385*c2c66affSColin Finck             "incorrect iid value\n");
1386*c2c66affSColin Finck     ok(!dest[0].pUnk, "pUnk != NULL\n");
1387*c2c66affSColin Finck     ok(src[0].dwReserved == dest[0].dwReserved, "dwReserved = %x, expected %x\n",
1388*c2c66affSColin Finck             dest[0].dwReserved, src[0].dwReserved);
1389*c2c66affSColin Finck 
1390*c2c66affSColin Finck     CoTaskMemFree(src[0].szExtraInfo);
1391*c2c66affSColin Finck     CoTaskMemFree(dest[0].szExtraInfo);
1392*c2c66affSColin Finck 
1393*c2c66affSColin Finck     src[0].szExtraInfo = NULL;
1394*c2c66affSColin Finck     src[0].securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
1395*c2c66affSColin Finck     ok(InitializeSecurityDescriptor(&sec_desc, SECURITY_DESCRIPTOR_REVISION),
1396*c2c66affSColin Finck             "InitializeSecurityDescriptor failed\n");
1397*c2c66affSColin Finck     src[0].securityAttributes.lpSecurityDescriptor = (void*)&sec_desc;
1398*c2c66affSColin Finck     src[0].securityAttributes.bInheritHandle = TRUE;
1399*c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1400*c2c66affSColin Finck     ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1401*c2c66affSColin Finck     ok(!dest[0].securityAttributes.nLength,
1402*c2c66affSColin Finck             "unexpected securityAttributes.nLength value: %d\n",
1403*c2c66affSColin Finck             dest[0].securityAttributes.nLength);
1404*c2c66affSColin Finck     ok(!dest[0].securityAttributes.lpSecurityDescriptor,
1405*c2c66affSColin Finck             "unexpected securityAttributes.lpSecurityDescriptor value: %p\n",
1406*c2c66affSColin Finck             dest[0].securityAttributes.lpSecurityDescriptor);
1407*c2c66affSColin Finck     ok(!dest[0].securityAttributes.bInheritHandle,
1408*c2c66affSColin Finck             "unexpected securityAttributes.bInheritHandle value: %d\n",
1409*c2c66affSColin Finck             dest[0].securityAttributes.bInheritHandle);
1410*c2c66affSColin Finck }
1411*c2c66affSColin Finck 
1412*c2c66affSColin Finck static void test_UrlMkGetSessionOption(void)
1413*c2c66affSColin Finck {
1414*c2c66affSColin Finck     DWORD encoding, size;
1415*c2c66affSColin Finck     HRESULT hres;
1416*c2c66affSColin Finck 
1417*c2c66affSColin Finck     size = encoding = 0xdeadbeef;
1418*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1419*c2c66affSColin Finck                                  sizeof(encoding), &size, 0);
1420*c2c66affSColin Finck     ok(hres == S_OK, "UrlMkGetSessionOption failed: %08x\n", hres);
1421*c2c66affSColin Finck     ok(encoding != 0xdeadbeef, "encoding not changed\n");
1422*c2c66affSColin Finck     ok(size == sizeof(encoding), "size=%d\n", size);
1423*c2c66affSColin Finck 
1424*c2c66affSColin Finck     size = encoding = 0xdeadbeef;
1425*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1426*c2c66affSColin Finck                                  sizeof(encoding)+1, &size, 0);
1427*c2c66affSColin Finck     ok(hres == S_OK, "UrlMkGetSessionOption failed: %08x\n", hres);
1428*c2c66affSColin Finck     ok(encoding != 0xdeadbeef, "encoding not changed\n");
1429*c2c66affSColin Finck     ok(size == sizeof(encoding), "size=%d\n", size);
1430*c2c66affSColin Finck 
1431*c2c66affSColin Finck     size = encoding = 0xdeadbeef;
1432*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1433*c2c66affSColin Finck                                  sizeof(encoding)-1, &size, 0);
1434*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1435*c2c66affSColin Finck     ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1436*c2c66affSColin Finck     ok(size == 0xdeadbeef, "size=%d\n", size);
1437*c2c66affSColin Finck 
1438*c2c66affSColin Finck     size = encoding = 0xdeadbeef;
1439*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, NULL,
1440*c2c66affSColin Finck                                  sizeof(encoding)-1, &size, 0);
1441*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1442*c2c66affSColin Finck     ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1443*c2c66affSColin Finck     ok(size == 0xdeadbeef, "size=%d\n", size);
1444*c2c66affSColin Finck 
1445*c2c66affSColin Finck     encoding = 0xdeadbeef;
1446*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1447*c2c66affSColin Finck                                  sizeof(encoding)-1, NULL, 0);
1448*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1449*c2c66affSColin Finck     ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1450*c2c66affSColin Finck }
1451*c2c66affSColin Finck 
1452*c2c66affSColin Finck static void test_user_agent(void)
1453*c2c66affSColin Finck {
1454*c2c66affSColin Finck     static const CHAR expected[] = "Mozilla/4.0 (compatible; MSIE ";
1455*c2c66affSColin Finck     static char test_str[] = "test";
1456*c2c66affSColin Finck     static char test2_str[] = "test\0test";
1457*c2c66affSColin Finck     static CHAR str[3];
1458*c2c66affSColin Finck     LPSTR str2 = NULL;
1459*c2c66affSColin Finck     HRESULT hres;
1460*c2c66affSColin Finck     DWORD size, saved;
1461*c2c66affSColin Finck 
1462*c2c66affSColin Finck     hres = pObtainUserAgentString(0, NULL, NULL);
1463*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "ObtainUserAgentString failed: %08x\n", hres);
1464*c2c66affSColin Finck 
1465*c2c66affSColin Finck     size = 100;
1466*c2c66affSColin Finck     hres = pObtainUserAgentString(0, NULL, &size);
1467*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "ObtainUserAgentString failed: %08x\n", hres);
1468*c2c66affSColin Finck     ok(size == 100, "size=%d, expected %d\n", size, 100);
1469*c2c66affSColin Finck 
1470*c2c66affSColin Finck     size = 0;
1471*c2c66affSColin Finck     hres = pObtainUserAgentString(0, str, &size);
1472*c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1473*c2c66affSColin Finck     ok(size > 0, "size=%d, expected non-zero\n", size);
1474*c2c66affSColin Finck 
1475*c2c66affSColin Finck     size = 2;
1476*c2c66affSColin Finck     str[0] = 'a';
1477*c2c66affSColin Finck     hres = pObtainUserAgentString(0, str, &size);
1478*c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1479*c2c66affSColin Finck     ok(size > 0, "size=%d, expected non-zero\n", size);
1480*c2c66affSColin Finck     ok(str[0] == 'a', "str[0]=%c, expected 'a'\n", str[0]);
1481*c2c66affSColin Finck 
1482*c2c66affSColin Finck     size = 0;
1483*c2c66affSColin Finck     hres = pObtainUserAgentString(1, str, &size);
1484*c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1485*c2c66affSColin Finck     ok(size > 0, "size=%d, expected non-zero\n", size);
1486*c2c66affSColin Finck 
1487*c2c66affSColin Finck     str2 = HeapAlloc(GetProcessHeap(), 0, (size+20)*sizeof(CHAR));
1488*c2c66affSColin Finck     saved = size;
1489*c2c66affSColin Finck     hres = pObtainUserAgentString(0, str2, &size);
1490*c2c66affSColin Finck     ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
1491*c2c66affSColin Finck     ok(size == saved, "size=%d, expected %d\n", size, saved);
1492*c2c66affSColin Finck     ok(strlen(expected) <= strlen(str2) &&
1493*c2c66affSColin Finck        !memcmp(expected, str2, strlen(expected)*sizeof(CHAR)),
1494*c2c66affSColin Finck        "user agent was \"%s\", expected to start with \"%s\"\n",
1495*c2c66affSColin Finck        str2, expected);
1496*c2c66affSColin Finck 
1497*c2c66affSColin Finck     size = saved+10;
1498*c2c66affSColin Finck     hres = pObtainUserAgentString(0, str2, &size);
1499*c2c66affSColin Finck     ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
1500*c2c66affSColin Finck     ok(size == saved, "size=%d, expected %d\n", size, saved);
1501*c2c66affSColin Finck 
1502*c2c66affSColin Finck     size = 0;
1503*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, NULL, 0, &size, 0);
1504*c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1505*c2c66affSColin Finck     ok(size, "size == 0\n");
1506*c2c66affSColin Finck 
1507*c2c66affSColin Finck     size = 0xdeadbeef;
1508*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, NULL, 1000, &size, 0);
1509*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1510*c2c66affSColin Finck     ok(size, "size == 0\n");
1511*c2c66affSColin Finck 
1512*c2c66affSColin Finck     saved = size;
1513*c2c66affSColin Finck     size = 0;
1514*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved+10, &size, 0);
1515*c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1516*c2c66affSColin Finck     ok(size == saved, "size = %d, expected %d\n", size, saved);
1517*c2c66affSColin Finck     ok(sizeof(expected) <= strlen(str2) && !memcmp(expected, str2, sizeof(expected)-1),
1518*c2c66affSColin Finck        "user agent was \"%s\", expected to start with \"%s\"\n",
1519*c2c66affSColin Finck        str2, expected);
1520*c2c66affSColin Finck 
1521*c2c66affSColin Finck     size = 0;
1522*c2c66affSColin Finck     str2[0] = 0;
1523*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1524*c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1525*c2c66affSColin Finck     ok(size == saved, "size = %d, expected %d\n", size, saved);
1526*c2c66affSColin Finck     ok(sizeof(expected) <= strlen(str2) && !memcmp(expected, str2, sizeof(expected)-1),
1527*c2c66affSColin Finck        "user agent was \"%s\", expected to start with \"%s\"\n",
1528*c2c66affSColin Finck        str2, expected);
1529*c2c66affSColin Finck 
1530*c2c66affSColin Finck     size = saved;
1531*c2c66affSColin Finck     str2[0] = 0;
1532*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved-1, &size, 0);
1533*c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1534*c2c66affSColin Finck     ok(size == saved, "size = %d, expected %d\n", size, saved);
1535*c2c66affSColin Finck     ok(!str2[0], "buf changed\n");
1536*c2c66affSColin Finck 
1537*c2c66affSColin Finck     size = saved;
1538*c2c66affSColin Finck     str2[0] = 0;
1539*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, NULL, 0);
1540*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1541*c2c66affSColin Finck     ok(!str2[0], "buf changed\n");
1542*c2c66affSColin Finck 
1543*c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, sizeof(test_str), 0);
1544*c2c66affSColin Finck     ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1545*c2c66affSColin Finck 
1546*c2c66affSColin Finck     size = 0;
1547*c2c66affSColin Finck     str2[0] = 0;
1548*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1549*c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1550*c2c66affSColin Finck     ok(size == sizeof(test_str) && !memcmp(str2, test_str, sizeof(test_str)), "wrong user agent\n");
1551*c2c66affSColin Finck 
1552*c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test2_str, sizeof(test2_str), 0);
1553*c2c66affSColin Finck     ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1554*c2c66affSColin Finck 
1555*c2c66affSColin Finck     size = 0;
1556*c2c66affSColin Finck     str2[0] = 0;
1557*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1558*c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1559*c2c66affSColin Finck     ok(size == sizeof(test_str) && !memcmp(str2, test_str, sizeof(test_str)), "wrong user agent\n");
1560*c2c66affSColin Finck 
1561*c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, 2, 0);
1562*c2c66affSColin Finck     ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1563*c2c66affSColin Finck 
1564*c2c66affSColin Finck     size = 0;
1565*c2c66affSColin Finck     str2[0] = 0;
1566*c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1567*c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1568*c2c66affSColin Finck     ok(size == 3 && !strcmp(str2, "te"), "wrong user agent\n");
1569*c2c66affSColin Finck 
1570*c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, 0, 0);
1571*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1572*c2c66affSColin Finck 
1573*c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, NULL, sizeof(test_str), 0);
1574*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1575*c2c66affSColin Finck 
1576*c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, NULL, 0, 0);
1577*c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1578*c2c66affSColin Finck 
1579*c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, str2);
1580*c2c66affSColin Finck }
1581*c2c66affSColin Finck 
1582*c2c66affSColin Finck static void test_MkParseDisplayNameEx(void)
1583*c2c66affSColin Finck {
1584*c2c66affSColin Finck     IMoniker *mon = NULL;
1585*c2c66affSColin Finck     LPWSTR name;
1586*c2c66affSColin Finck     DWORD issys;
1587*c2c66affSColin Finck     ULONG eaten = 0;
1588*c2c66affSColin Finck     IBindCtx *bctx;
1589*c2c66affSColin Finck     HRESULT hres;
1590*c2c66affSColin Finck 
1591*c2c66affSColin Finck     static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
1592*c2c66affSColin Finck             '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
1593*c2c66affSColin Finck             '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
1594*c2c66affSColin Finck 
1595*c2c66affSColin Finck     const struct
1596*c2c66affSColin Finck     {
1597*c2c66affSColin Finck         LPBC *ppbc;
1598*c2c66affSColin Finck         LPCWSTR szDisplayName;
1599*c2c66affSColin Finck         ULONG *pchEaten;
1600*c2c66affSColin Finck         LPMONIKER *ppmk;
1601*c2c66affSColin Finck     } invalid_parameters[] =
1602*c2c66affSColin Finck     {
1603*c2c66affSColin Finck         {NULL,  NULL,     NULL,   NULL},
1604*c2c66affSColin Finck         {NULL,  NULL,     NULL,   &mon},
1605*c2c66affSColin Finck         {NULL,  NULL,     &eaten, NULL},
1606*c2c66affSColin Finck         {NULL,  NULL,     &eaten, &mon},
1607*c2c66affSColin Finck         {NULL,  wszEmpty, NULL,   NULL},
1608*c2c66affSColin Finck         {NULL,  wszEmpty, NULL,   &mon},
1609*c2c66affSColin Finck         {NULL,  wszEmpty, &eaten, NULL},
1610*c2c66affSColin Finck         {NULL,  wszEmpty, &eaten, &mon},
1611*c2c66affSColin Finck         {&bctx, NULL,     NULL,   NULL},
1612*c2c66affSColin Finck         {&bctx, NULL,     NULL,   &mon},
1613*c2c66affSColin Finck         {&bctx, NULL,     &eaten, NULL},
1614*c2c66affSColin Finck         {&bctx, NULL,     &eaten, &mon},
1615*c2c66affSColin Finck         {&bctx, wszEmpty, NULL,   NULL},
1616*c2c66affSColin Finck         {&bctx, wszEmpty, NULL,   &mon},
1617*c2c66affSColin Finck         {&bctx, wszEmpty, &eaten, NULL},
1618*c2c66affSColin Finck         {&bctx, wszEmpty, &eaten, &mon},
1619*c2c66affSColin Finck     };
1620*c2c66affSColin Finck 
1621*c2c66affSColin Finck     int i;
1622*c2c66affSColin Finck 
1623*c2c66affSColin Finck     CreateBindCtx(0, &bctx);
1624*c2c66affSColin Finck 
1625*c2c66affSColin Finck     for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
1626*c2c66affSColin Finck     {
1627*c2c66affSColin Finck         eaten = 0xdeadbeef;
1628*c2c66affSColin Finck         mon = (IMoniker *)0xdeadbeef;
1629*c2c66affSColin Finck         hres = MkParseDisplayNameEx(invalid_parameters[i].ppbc ? *invalid_parameters[i].ppbc : NULL,
1630*c2c66affSColin Finck                                     invalid_parameters[i].szDisplayName,
1631*c2c66affSColin Finck                                     invalid_parameters[i].pchEaten,
1632*c2c66affSColin Finck                                     invalid_parameters[i].ppmk);
1633*c2c66affSColin Finck         ok(hres == E_INVALIDARG,
1634*c2c66affSColin Finck             "[%d] Expected MkParseDisplayNameEx to return E_INVALIDARG, got %08x\n", i, hres);
1635*c2c66affSColin Finck         ok(eaten == 0xdeadbeef, "[%d] Expected eaten to be 0xdeadbeef, got %u\n", i, eaten);
1636*c2c66affSColin Finck         ok(mon == (IMoniker *)0xdeadbeef, "[%d] Expected mon to be 0xdeadbeef, got %p\n", i, mon);
1637*c2c66affSColin Finck     }
1638*c2c66affSColin Finck 
1639*c2c66affSColin Finck     hres = MkParseDisplayNameEx(bctx, url9, &eaten, &mon);
1640*c2c66affSColin Finck     ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
1641*c2c66affSColin Finck     ok(eaten == sizeof(url9)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
1642*c2c66affSColin Finck     ok(mon != NULL, "mon == NULL\n");
1643*c2c66affSColin Finck 
1644*c2c66affSColin Finck     hres = IMoniker_GetDisplayName(mon, NULL, 0, &name);
1645*c2c66affSColin Finck     ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1646*c2c66affSColin Finck     ok(!lstrcmpW(name, url9), "wrong display name %s\n", wine_dbgstr_w(name));
1647*c2c66affSColin Finck     CoTaskMemFree(name);
1648*c2c66affSColin Finck 
1649*c2c66affSColin Finck     hres = IMoniker_IsSystemMoniker(mon, &issys);
1650*c2c66affSColin Finck     ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
1651*c2c66affSColin Finck     ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
1652*c2c66affSColin Finck 
1653*c2c66affSColin Finck     IMoniker_Release(mon);
1654*c2c66affSColin Finck 
1655*c2c66affSColin Finck     hres = MkParseDisplayNameEx(bctx, clsid_nameW, &eaten, &mon);
1656*c2c66affSColin Finck     ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
1657*c2c66affSColin Finck     ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
1658*c2c66affSColin Finck     ok(mon != NULL, "mon == NULL\n");
1659*c2c66affSColin Finck 
1660*c2c66affSColin Finck     hres = IMoniker_IsSystemMoniker(mon, &issys);
1661*c2c66affSColin Finck     ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
1662*c2c66affSColin Finck     ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
1663*c2c66affSColin Finck 
1664*c2c66affSColin Finck     IMoniker_Release(mon);
1665*c2c66affSColin Finck 
1666*c2c66affSColin Finck     hres = MkParseDisplayNameEx(bctx, url8, &eaten, &mon);
1667*c2c66affSColin Finck     ok(FAILED(hres), "MkParseDisplayNameEx succeeded: %08x\n", hres);
1668*c2c66affSColin Finck 
1669*c2c66affSColin Finck     IBindCtx_Release(bctx);
1670*c2c66affSColin Finck }
1671*c2c66affSColin Finck 
1672*c2c66affSColin Finck static void test_IsValidURL(void)
1673*c2c66affSColin Finck {
1674*c2c66affSColin Finck     HRESULT hr;
1675*c2c66affSColin Finck     IBindCtx *bctx = NULL;
1676*c2c66affSColin Finck 
1677*c2c66affSColin Finck     hr = IsValidURL(NULL, 0, 0);
1678*c2c66affSColin Finck     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1679*c2c66affSColin Finck 
1680*c2c66affSColin Finck     hr = IsValidURL(NULL, wszHttpWineHQ, 0);
1681*c2c66affSColin Finck     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1682*c2c66affSColin Finck 
1683*c2c66affSColin Finck     CreateBindCtx(0, &bctx);
1684*c2c66affSColin Finck 
1685*c2c66affSColin Finck     hr = IsValidURL(bctx, wszHttpWineHQ, 0);
1686*c2c66affSColin Finck     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1687*c2c66affSColin Finck 
1688*c2c66affSColin Finck     IBindCtx_Release(bctx);
1689*c2c66affSColin Finck }
1690*c2c66affSColin Finck 
1691*c2c66affSColin Finck static const struct {
1692*c2c66affSColin Finck     INTERNETFEATURELIST feature;
1693*c2c66affSColin Finck     DWORD               get_flags;
1694*c2c66affSColin Finck     HRESULT             expected;
1695*c2c66affSColin Finck     BOOL                todo;
1696*c2c66affSColin Finck } default_feature_tests[] = {
1697*c2c66affSColin Finck     {FEATURE_OBJECT_CACHING,GET_FEATURE_FROM_PROCESS,S_OK},
1698*c2c66affSColin Finck     {FEATURE_ZONE_ELEVATION,GET_FEATURE_FROM_PROCESS,S_FALSE},
1699*c2c66affSColin Finck     {FEATURE_MIME_HANDLING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1700*c2c66affSColin Finck     {FEATURE_MIME_SNIFFING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1701*c2c66affSColin Finck     {FEATURE_WINDOW_RESTRICTIONS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1702*c2c66affSColin Finck     {FEATURE_WEBOC_POPUPMANAGEMENT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1703*c2c66affSColin Finck     {FEATURE_BEHAVIORS,GET_FEATURE_FROM_PROCESS,S_OK},
1704*c2c66affSColin Finck     {FEATURE_DISABLE_MK_PROTOCOL,GET_FEATURE_FROM_PROCESS,S_OK},
1705*c2c66affSColin Finck     {FEATURE_LOCALMACHINE_LOCKDOWN,GET_FEATURE_FROM_PROCESS,S_FALSE},
1706*c2c66affSColin Finck     {FEATURE_SECURITYBAND,GET_FEATURE_FROM_PROCESS,S_FALSE},
1707*c2c66affSColin Finck     {FEATURE_RESTRICT_ACTIVEXINSTALL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1708*c2c66affSColin Finck     {FEATURE_VALIDATE_NAVIGATE_URL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1709*c2c66affSColin Finck     {FEATURE_RESTRICT_FILEDOWNLOAD,GET_FEATURE_FROM_PROCESS,S_FALSE},
1710*c2c66affSColin Finck     {FEATURE_ADDON_MANAGEMENT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1711*c2c66affSColin Finck     {FEATURE_PROTOCOL_LOCKDOWN,GET_FEATURE_FROM_PROCESS,S_FALSE},
1712*c2c66affSColin Finck     {FEATURE_HTTP_USERNAME_PASSWORD_DISABLE,GET_FEATURE_FROM_PROCESS,S_FALSE},
1713*c2c66affSColin Finck     {FEATURE_SAFE_BINDTOOBJECT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1714*c2c66affSColin Finck     {FEATURE_UNC_SAVEDFILECHECK,GET_FEATURE_FROM_PROCESS,S_FALSE},
1715*c2c66affSColin Finck     {FEATURE_GET_URL_DOM_FILEPATH_UNENCODED,GET_FEATURE_FROM_PROCESS,S_OK},
1716*c2c66affSColin Finck     {FEATURE_TABBED_BROWSING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1717*c2c66affSColin Finck     {FEATURE_SSLUX,GET_FEATURE_FROM_PROCESS,S_FALSE},
1718*c2c66affSColin Finck     {FEATURE_DISABLE_NAVIGATION_SOUNDS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1719*c2c66affSColin Finck     {FEATURE_DISABLE_LEGACY_COMPRESSION,GET_FEATURE_FROM_PROCESS,S_OK},
1720*c2c66affSColin Finck     {FEATURE_FORCE_ADDR_AND_STATUS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1721*c2c66affSColin Finck     {FEATURE_XMLHTTP,GET_FEATURE_FROM_PROCESS,S_OK},
1722*c2c66affSColin Finck     {FEATURE_DISABLE_TELNET_PROTOCOL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1723*c2c66affSColin Finck     {FEATURE_FEEDS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1724*c2c66affSColin Finck     {FEATURE_BLOCK_INPUT_PROMPTS,GET_FEATURE_FROM_PROCESS,S_FALSE}
1725*c2c66affSColin Finck };
1726*c2c66affSColin Finck 
1727*c2c66affSColin Finck static void test_internet_feature_defaults(void) {
1728*c2c66affSColin Finck     HRESULT hres;
1729*c2c66affSColin Finck     DWORD i;
1730*c2c66affSColin Finck 
1731*c2c66affSColin Finck     for(i = 0; i < sizeof(default_feature_tests)/sizeof(default_feature_tests[0]); ++i) {
1732*c2c66affSColin Finck         hres = pCoInternetIsFeatureEnabled(default_feature_tests[i].feature, default_feature_tests[i].get_flags);
1733*c2c66affSColin Finck         todo_wine_if (default_feature_tests[i].todo)
1734*c2c66affSColin Finck             ok(hres == default_feature_tests[i].expected, "CoInternetIsFeatureEnabled returned %08x, expected %08x on test %d\n",
1735*c2c66affSColin Finck                 hres, default_feature_tests[i].expected, i);
1736*c2c66affSColin Finck     }
1737*c2c66affSColin Finck }
1738*c2c66affSColin Finck 
1739*c2c66affSColin Finck /* With older versions of IE (IE 7 and earlier), urlmon caches
1740*c2c66affSColin Finck  * the FeatureControl values from the registry when it's loaded
1741*c2c66affSColin Finck  * into memory. Newer versions of IE conditionally cache the
1742*c2c66affSColin Finck  * the FeatureControl registry values (i.e. When a call to
1743*c2c66affSColin Finck  * CoInternetIsFeatureEnabled and a corresponding CoInternetSetFeatureEnabled
1744*c2c66affSColin Finck  * call hasn't already been made for the specified Feature). Because of
1745*c2c66affSColin Finck  * this we skip these tests on IE 7 and earlier.
1746*c2c66affSColin Finck  */
1747*c2c66affSColin Finck static const char* szFeatureControlKey = "Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl";
1748*c2c66affSColin Finck 
1749*c2c66affSColin Finck static void test_internet_features_registry(void) {
1750*c2c66affSColin Finck     HRESULT hres;
1751*c2c66affSColin Finck     DWORD res;
1752*c2c66affSColin Finck     char module[MAX_PATH];
1753*c2c66affSColin Finck     char *name;
1754*c2c66affSColin Finck     HKEY feature_control;
1755*c2c66affSColin Finck     HKEY feature;
1756*c2c66affSColin Finck     DWORD value;
1757*c2c66affSColin Finck     BOOL skip_zone;
1758*c2c66affSColin Finck     BOOL delete_feature_key = TRUE;
1759*c2c66affSColin Finck 
1760*c2c66affSColin Finck     static const char* szFeatureBehaviorsKey = "FEATURE_BEHAVIORS";
1761*c2c66affSColin Finck     static const char* szFeatureZoneElevationKey = "FEATURE_ZONE_ELEVATION";
1762*c2c66affSColin Finck 
1763*c2c66affSColin Finck     if(!pIEInstallScope) {
1764*c2c66affSColin Finck         win_skip("Skipping internet feature registry tests, IE is too old...\n");
1765*c2c66affSColin Finck         return;
1766*c2c66affSColin Finck     }
1767*c2c66affSColin Finck 
1768*c2c66affSColin Finck     res = GetModuleFileNameA(NULL, module, sizeof(module));
1769*c2c66affSColin Finck     ok(res, "GetModuleFileName failed: %d\n", GetLastError());
1770*c2c66affSColin Finck 
1771*c2c66affSColin Finck     name = strrchr(module, '\\')+1;
1772*c2c66affSColin Finck 
1773*c2c66affSColin Finck     /* Some Windows machines don't have a FeatureControl key in HKCU. */
1774*c2c66affSColin Finck     res = RegOpenKeyA(HKEY_CURRENT_USER, szFeatureControlKey, &feature_control);
1775*c2c66affSColin Finck     ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1776*c2c66affSColin Finck 
1777*c2c66affSColin Finck     res = RegOpenKeyA(feature_control, szFeatureBehaviorsKey, &feature);
1778*c2c66affSColin Finck     if(res == ERROR_SUCCESS) {
1779*c2c66affSColin Finck         /* FEATURE_BEHAVIORS already existed, so don't delete it when we're done. */
1780*c2c66affSColin Finck         delete_feature_key = FALSE;
1781*c2c66affSColin Finck     }else {
1782*c2c66affSColin Finck         res = RegCreateKeyA(feature_control, szFeatureBehaviorsKey, &feature);
1783*c2c66affSColin Finck         ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1784*c2c66affSColin Finck     }
1785*c2c66affSColin Finck 
1786*c2c66affSColin Finck     value = 0;
1787*c2c66affSColin Finck     res = RegSetValueExA(feature, name, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
1788*c2c66affSColin Finck     ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
1789*c2c66affSColin Finck 
1790*c2c66affSColin Finck     hres = pCoInternetIsFeatureEnabled(FEATURE_BEHAVIORS, GET_FEATURE_FROM_PROCESS);
1791*c2c66affSColin Finck     ok(hres == S_FALSE, "CoInternetIsFeatureEnabled returned %08x, expected S_FALSE\n", hres);
1792*c2c66affSColin Finck 
1793*c2c66affSColin Finck     if(delete_feature_key) {
1794*c2c66affSColin Finck         RegCloseKey(feature);
1795*c2c66affSColin Finck         RegDeleteKeyA(feature_control, szFeatureBehaviorsKey);
1796*c2c66affSColin Finck     } else {
1797*c2c66affSColin Finck         RegDeleteValueA(feature, name);
1798*c2c66affSColin Finck         RegCloseKey(feature);
1799*c2c66affSColin Finck     }
1800*c2c66affSColin Finck 
1801*c2c66affSColin Finck     /* IE's feature control cached the value it got from the registry earlier. */
1802*c2c66affSColin Finck     hres = pCoInternetIsFeatureEnabled(FEATURE_BEHAVIORS, GET_FEATURE_FROM_PROCESS);
1803*c2c66affSColin Finck     ok(hres == S_FALSE, "CoInternetIsFeatureEnabled returned %08x, expected S_FALSE\n", hres);
1804*c2c66affSColin Finck 
1805*c2c66affSColin Finck     /* Restore this feature back to its default value. */
1806*c2c66affSColin Finck     hres = pCoInternetSetFeatureEnabled(FEATURE_BEHAVIORS, SET_FEATURE_ON_PROCESS, TRUE);
1807*c2c66affSColin Finck     ok(hres == S_OK, "CoInternetSetFeatureEnabled failed: %08x\n", hres);
1808*c2c66affSColin Finck 
1809*c2c66affSColin Finck     RegCloseKey(feature_control);
1810*c2c66affSColin Finck 
1811*c2c66affSColin Finck     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, szFeatureControlKey, &feature_control);
1812*c2c66affSColin Finck     ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
1813*c2c66affSColin Finck 
1814*c2c66affSColin Finck     res = RegOpenKeyA(feature_control, szFeatureZoneElevationKey, &feature);
1815*c2c66affSColin Finck     ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
1816*c2c66affSColin Finck 
1817*c2c66affSColin Finck     value = 1;
1818*c2c66affSColin Finck     res = RegSetValueExA(feature, "*", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
1819*c2c66affSColin Finck     if (res == ERROR_ACCESS_DENIED)
1820*c2c66affSColin Finck     {
1821*c2c66affSColin Finck         skip("Not allowed to modify zone elevation\n");
1822*c2c66affSColin Finck         skip_zone = TRUE;
1823*c2c66affSColin Finck     }
1824*c2c66affSColin Finck     else
1825*c2c66affSColin Finck     {
1826*c2c66affSColin Finck         skip_zone = FALSE;
1827*c2c66affSColin Finck         ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
1828*c2c66affSColin Finck 
1829*c2c66affSColin Finck         hres = pCoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, GET_FEATURE_FROM_PROCESS);
1830*c2c66affSColin Finck         ok(hres == S_OK, "CoInternetIsFeatureEnabled returned %08x, expected S_OK\n", hres);
1831*c2c66affSColin Finck     }
1832*c2c66affSColin Finck     RegDeleteValueA(feature, "*");
1833*c2c66affSColin Finck     RegCloseKey(feature);
1834*c2c66affSColin Finck     RegCloseKey(feature_control);
1835*c2c66affSColin Finck 
1836*c2c66affSColin Finck     /* Value is still cached from last time. */
1837*c2c66affSColin Finck     if (!skip_zone)
1838*c2c66affSColin Finck     {
1839*c2c66affSColin Finck         hres = pCoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, GET_FEATURE_FROM_PROCESS);
1840*c2c66affSColin Finck         ok(hres == S_OK, "CoInternetIsFeatureEnabled returned %08x, expected S_OK\n", hres);
1841*c2c66affSColin Finck 
1842*c2c66affSColin Finck         hres = pCoInternetSetFeatureEnabled(FEATURE_ZONE_ELEVATION, SET_FEATURE_ON_PROCESS, FALSE);
1843*c2c66affSColin Finck         ok(hres == S_OK, "CoInternetSetFeatureEnabled failed: %08x\n", hres);
1844*c2c66affSColin Finck     }
1845*c2c66affSColin Finck 
1846*c2c66affSColin Finck     test_internet_feature_defaults();
1847*c2c66affSColin Finck }
1848*c2c66affSColin Finck 
1849*c2c66affSColin Finck static void test_CoInternetIsFeatureEnabled(void) {
1850*c2c66affSColin Finck     HRESULT hres;
1851*c2c66affSColin Finck 
1852*c2c66affSColin Finck     hres = pCoInternetIsFeatureEnabled(FEATURE_ENTRY_COUNT, GET_FEATURE_FROM_PROCESS);
1853*c2c66affSColin Finck     ok(hres == E_FAIL, "CoInternetIsFeatureEnabled returned %08x, expected E_FAIL\n", hres);
1854*c2c66affSColin Finck }
1855*c2c66affSColin Finck 
1856*c2c66affSColin Finck static const struct {
1857*c2c66affSColin Finck     INTERNETFEATURELIST feature;
1858*c2c66affSColin Finck     DWORD               set_flags;
1859*c2c66affSColin Finck     BOOL                enable;
1860*c2c66affSColin Finck     HRESULT             set_expected;
1861*c2c66affSColin Finck     BOOL                set_todo;
1862*c2c66affSColin Finck     DWORD               get_flags;
1863*c2c66affSColin Finck     HRESULT             get_expected;
1864*c2c66affSColin Finck     BOOL                get_todo;
1865*c2c66affSColin Finck } internet_feature_tests[] = {
1866*c2c66affSColin Finck     {FEATURE_OBJECT_CACHING,SET_FEATURE_ON_PROCESS,FALSE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_FALSE},
1867*c2c66affSColin Finck     {FEATURE_WEBOC_POPUPMANAGEMENT,SET_FEATURE_ON_PROCESS,TRUE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_OK},
1868*c2c66affSColin Finck     {FEATURE_LOCALMACHINE_LOCKDOWN,SET_FEATURE_ON_PROCESS,TRUE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_OK}
1869*c2c66affSColin Finck };
1870*c2c66affSColin Finck 
1871*c2c66affSColin Finck static void test_CoInternetSetFeatureEnabled(void) {
1872*c2c66affSColin Finck     HRESULT hres;
1873*c2c66affSColin Finck     DWORD i;
1874*c2c66affSColin Finck 
1875*c2c66affSColin Finck     hres = pCoInternetSetFeatureEnabled(FEATURE_ENTRY_COUNT,SET_FEATURE_ON_PROCESS,TRUE);
1876*c2c66affSColin Finck     ok(hres == E_FAIL, "CoInternetSetFeatureEnabled returned %08x, expected E_FAIL\n", hres);
1877*c2c66affSColin Finck 
1878*c2c66affSColin Finck     for(i = 0; i < sizeof(internet_feature_tests)/sizeof(internet_feature_tests[0]); ++i) {
1879*c2c66affSColin Finck         hres = pCoInternetSetFeatureEnabled(internet_feature_tests[i].feature, internet_feature_tests[i].set_flags,
1880*c2c66affSColin Finck                                             internet_feature_tests[i].enable);
1881*c2c66affSColin Finck         todo_wine_if (internet_feature_tests[i].set_todo)
1882*c2c66affSColin Finck             ok(hres == internet_feature_tests[i].set_expected, "CoInternetSetFeatureEnabled returned %08x, expected %08x on test %d\n",
1883*c2c66affSColin Finck                 hres, internet_feature_tests[i].set_expected, i);
1884*c2c66affSColin Finck 
1885*c2c66affSColin Finck         hres = pCoInternetIsFeatureEnabled(internet_feature_tests[i].feature, internet_feature_tests[i].set_flags);
1886*c2c66affSColin Finck         todo_wine_if (internet_feature_tests[i].get_todo)
1887*c2c66affSColin Finck             ok(hres == internet_feature_tests[i].get_expected, "CoInternetIsFeatureEnabled returned %08x, expected %08x on test %d\n",
1888*c2c66affSColin Finck                 hres, internet_feature_tests[i].get_expected, i);
1889*c2c66affSColin Finck 
1890*c2c66affSColin Finck     }
1891*c2c66affSColin Finck }
1892*c2c66affSColin Finck 
1893*c2c66affSColin Finck static void test_internet_features(void) {
1894*c2c66affSColin Finck     HKEY key;
1895*c2c66affSColin Finck     DWORD res;
1896*c2c66affSColin Finck 
1897*c2c66affSColin Finck     if(!pCoInternetIsFeatureEnabled || !pCoInternetSetFeatureEnabled) {
1898*c2c66affSColin Finck         win_skip("Skipping internet feature tests, IE is too old\n");
1899*c2c66affSColin Finck         return;
1900*c2c66affSColin Finck     }
1901*c2c66affSColin Finck 
1902*c2c66affSColin Finck     /* IE10 takes FeatureControl key into account only if it's available upon process start. */
1903*c2c66affSColin Finck     res = RegOpenKeyA(HKEY_CURRENT_USER, szFeatureControlKey, &key);
1904*c2c66affSColin Finck     if(res != ERROR_SUCCESS) {
1905*c2c66affSColin Finck         PROCESS_INFORMATION pi;
1906*c2c66affSColin Finck         STARTUPINFOA si = { 0 };
1907*c2c66affSColin Finck         char cmdline[MAX_PATH];
1908*c2c66affSColin Finck         char **argv;
1909*c2c66affSColin Finck         BOOL ret;
1910*c2c66affSColin Finck 
1911*c2c66affSColin Finck         res = RegCreateKeyA(HKEY_CURRENT_USER, szFeatureControlKey, &key);
1912*c2c66affSColin Finck         ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1913*c2c66affSColin Finck 
1914*c2c66affSColin Finck         trace("Running features tests in a separated process.\n");
1915*c2c66affSColin Finck 
1916*c2c66affSColin Finck         winetest_get_mainargs( &argv );
1917*c2c66affSColin Finck         sprintf(cmdline, "\"%s\" %s internet_features", argv[0], argv[1]);
1918*c2c66affSColin Finck         ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
1919*c2c66affSColin Finck         ok(ret, "Could not create process: %u\n", GetLastError());
1920*c2c66affSColin Finck         winetest_wait_child_process( pi.hProcess );
1921*c2c66affSColin Finck         CloseHandle(pi.hThread);
1922*c2c66affSColin Finck         CloseHandle(pi.hProcess);
1923*c2c66affSColin Finck 
1924*c2c66affSColin Finck         RegDeleteKeyA(HKEY_CURRENT_USER, szFeatureControlKey);
1925*c2c66affSColin Finck         return;
1926*c2c66affSColin Finck     }
1927*c2c66affSColin Finck 
1928*c2c66affSColin Finck     test_internet_features_registry();
1929*c2c66affSColin Finck     test_CoInternetIsFeatureEnabled();
1930*c2c66affSColin Finck     test_CoInternetSetFeatureEnabled();
1931*c2c66affSColin Finck }
1932*c2c66affSColin Finck 
1933*c2c66affSColin Finck START_TEST(misc)
1934*c2c66affSColin Finck {
1935*c2c66affSColin Finck     HMODULE hurlmon;
1936*c2c66affSColin Finck     int argc;
1937*c2c66affSColin Finck     char **argv;
1938*c2c66affSColin Finck 
1939*c2c66affSColin Finck     argc = winetest_get_mainargs(&argv);
1940*c2c66affSColin Finck 
1941*c2c66affSColin Finck     hurlmon = GetModuleHandleA("urlmon.dll");
1942*c2c66affSColin Finck     pCoInternetCompareUrl = (void *) GetProcAddress(hurlmon, "CoInternetCompareUrl");
1943*c2c66affSColin Finck     pCoInternetGetSecurityUrl = (void*) GetProcAddress(hurlmon, "CoInternetGetSecurityUrl");
1944*c2c66affSColin Finck     pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
1945*c2c66affSColin Finck     pCoInternetParseUrl = (void*) GetProcAddress(hurlmon, "CoInternetParseUrl");
1946*c2c66affSColin Finck     pCoInternetQueryInfo = (void*) GetProcAddress(hurlmon, "CoInternetQueryInfo");
1947*c2c66affSColin Finck     pCopyStgMedium = (void*) GetProcAddress(hurlmon, "CopyStgMedium");
1948*c2c66affSColin Finck     pCopyBindInfo = (void*) GetProcAddress(hurlmon, "CopyBindInfo");
1949*c2c66affSColin Finck     pFindMimeFromData = (void*) GetProcAddress(hurlmon, "FindMimeFromData");
1950*c2c66affSColin Finck     pObtainUserAgentString = (void*) GetProcAddress(hurlmon, "ObtainUserAgentString");
1951*c2c66affSColin Finck     pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
1952*c2c66affSColin Finck     pUrlMkGetSessionOption = (void*) GetProcAddress(hurlmon, "UrlMkGetSessionOption");
1953*c2c66affSColin Finck     pCompareSecurityIds = (void*) GetProcAddress(hurlmon, "CompareSecurityIds");
1954*c2c66affSColin Finck     pCoInternetIsFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetIsFeatureEnabled");
1955*c2c66affSColin Finck     pCoInternetSetFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetSetFeatureEnabled");
1956*c2c66affSColin Finck     pIEInstallScope = (void*) GetProcAddress(hurlmon, "IEInstallScope");
1957*c2c66affSColin Finck 
1958*c2c66affSColin Finck     if (!pCoInternetCompareUrl || !pCoInternetGetSecurityUrl ||
1959*c2c66affSColin Finck         !pCoInternetGetSession || !pCoInternetParseUrl || !pCompareSecurityIds) {
1960*c2c66affSColin Finck         win_skip("Various needed functions not present, too old IE\n");
1961*c2c66affSColin Finck         return;
1962*c2c66affSColin Finck     }
1963*c2c66affSColin Finck 
1964*c2c66affSColin Finck     OleInitialize(NULL);
1965*c2c66affSColin Finck 
1966*c2c66affSColin Finck     if(argc <= 2 || strcmp(argv[2], "internet_features")) {
1967*c2c66affSColin Finck         register_protocols();
1968*c2c66affSColin Finck 
1969*c2c66affSColin Finck         test_CreateFormatEnum();
1970*c2c66affSColin Finck         test_RegisterFormatEnumerator();
1971*c2c66affSColin Finck         test_CoInternetParseUrl();
1972*c2c66affSColin Finck         test_CoInternetCompareUrl();
1973*c2c66affSColin Finck         test_CoInternetQueryInfo();
1974*c2c66affSColin Finck         test_FindMimeFromData();
1975*c2c66affSColin Finck         test_NameSpace();
1976*c2c66affSColin Finck         test_MimeFilter();
1977*c2c66affSColin Finck         test_ReleaseBindInfo();
1978*c2c66affSColin Finck         test_CopyStgMedium();
1979*c2c66affSColin Finck         test_CopyBindInfo();
1980*c2c66affSColin Finck         test_UrlMkGetSessionOption();
1981*c2c66affSColin Finck         test_user_agent();
1982*c2c66affSColin Finck         test_MkParseDisplayNameEx();
1983*c2c66affSColin Finck         test_IsValidURL();
1984*c2c66affSColin Finck     }
1985*c2c66affSColin Finck 
1986*c2c66affSColin Finck     test_internet_features();
1987*c2c66affSColin Finck 
1988*c2c66affSColin Finck     OleUninitialize();
1989*c2c66affSColin Finck }
1990