1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Copyright 2005-2006 Jacek Caban for CodeWeavers
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck  * License as published by the Free Software Foundation; either
7c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck  *
9c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12c2c66affSColin Finck  * Lesser General Public License for more details.
13c2c66affSColin Finck  *
14c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17c2c66affSColin Finck  */
18c2c66affSColin Finck 
19c2c66affSColin Finck #define COBJMACROS
20c2c66affSColin Finck #define CONST_VTABLE
21c2c66affSColin Finck #define NONAMELESSUNION
22c2c66affSColin Finck 
23c2c66affSColin Finck #include <wine/test.h>
247f95c141SAmine Khaldi #include <stdarg.h>
257f95c141SAmine Khaldi #include <stddef.h>
26c2c66affSColin Finck #include <stdio.h>
27c2c66affSColin Finck 
287f95c141SAmine Khaldi #include "windef.h"
297f95c141SAmine Khaldi #include "winbase.h"
307f95c141SAmine Khaldi #include "ole2.h"
317f95c141SAmine Khaldi #include "urlmon.h"
32c2c66affSColin Finck 
337f95c141SAmine Khaldi #include "initguid.h"
347f95c141SAmine Khaldi #include "wine/heap.h"
35c2c66affSColin Finck 
36c2c66affSColin Finck DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
37c2c66affSColin Finck 
38c2c66affSColin Finck #define DEFINE_EXPECT(func) \
39c2c66affSColin Finck     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
40c2c66affSColin Finck 
41c2c66affSColin Finck #define SET_EXPECT(func) \
42c2c66affSColin Finck     expect_ ## func = TRUE
43c2c66affSColin Finck 
44c2c66affSColin Finck #define CHECK_EXPECT(func) \
45c2c66affSColin Finck     do { \
46c2c66affSColin Finck         ok(expect_ ##func, "unexpected call " #func "\n"); \
47c2c66affSColin Finck         expect_ ## func = FALSE; \
48c2c66affSColin Finck         called_ ## func = TRUE; \
49c2c66affSColin Finck     }while(0)
50c2c66affSColin Finck 
51c2c66affSColin Finck #define CHECK_EXPECT2(func) \
52c2c66affSColin Finck     do { \
53c2c66affSColin Finck         ok(expect_ ##func, "unexpected call " #func "\n"); \
54c2c66affSColin Finck         called_ ## func = TRUE; \
55c2c66affSColin Finck     }while(0)
56c2c66affSColin Finck 
57c2c66affSColin Finck #define CHECK_CALLED(func) \
58c2c66affSColin Finck     do { \
59c2c66affSColin Finck         ok(called_ ## func, "expected " #func "\n"); \
60c2c66affSColin Finck         expect_ ## func = called_ ## func = FALSE; \
61c2c66affSColin Finck     }while(0)
62c2c66affSColin Finck 
63c2c66affSColin Finck DEFINE_EXPECT(ParseUrl);
64*98e4a3ecSAmine Khaldi DEFINE_EXPECT(ParseUrl_ENCODE);
65*98e4a3ecSAmine Khaldi DEFINE_EXPECT(ParseUrl_UNESCAPE);
66c2c66affSColin Finck DEFINE_EXPECT(QI_IInternetProtocolInfo);
67c2c66affSColin Finck DEFINE_EXPECT(CreateInstance);
68c2c66affSColin Finck DEFINE_EXPECT(unk_Release);
69c2c66affSColin Finck 
70c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetCompareUrl)(LPCWSTR, LPCWSTR, DWORD);
71c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetGetSecurityUrl)(LPCWSTR, LPWSTR*, PSUACTION, DWORD);
72c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession **, DWORD);
73c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetParseUrl)(LPCWSTR, PARSEACTION, DWORD, LPWSTR, DWORD, DWORD *, DWORD);
74c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetQueryInfo)(LPCWSTR, QUERYOPTION, DWORD, LPVOID, DWORD, DWORD *, DWORD);
75c2c66affSColin Finck static HRESULT (WINAPI *pCopyStgMedium)(const STGMEDIUM *, STGMEDIUM *);
76c2c66affSColin Finck static HRESULT (WINAPI *pCopyBindInfo)(const BINDINFO *, BINDINFO *);
77c2c66affSColin Finck static HRESULT (WINAPI *pFindMimeFromData)(LPBC, LPCWSTR, LPVOID, DWORD, LPCWSTR,
78c2c66affSColin Finck                         DWORD, LPWSTR*, DWORD);
79c2c66affSColin Finck static HRESULT (WINAPI *pObtainUserAgentString)(DWORD, LPSTR, DWORD*);
80c2c66affSColin Finck static HRESULT (WINAPI *pReleaseBindInfo)(BINDINFO*);
81c2c66affSColin Finck static HRESULT (WINAPI *pUrlMkGetSessionOption)(DWORD, LPVOID, DWORD, DWORD *, DWORD);
82c2c66affSColin Finck static HRESULT (WINAPI *pCompareSecurityIds)(BYTE*,DWORD,BYTE*,DWORD,DWORD);
83c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetIsFeatureEnabled)(INTERNETFEATURELIST,DWORD);
84c2c66affSColin Finck static HRESULT (WINAPI *pCoInternetSetFeatureEnabled)(INTERNETFEATURELIST,DWORD,BOOL);
85c2c66affSColin Finck static HRESULT (WINAPI *pIEInstallScope)(DWORD*);
86c2c66affSColin Finck 
strcmp_wa(const WCHAR * strw,const char * stra)87c2c66affSColin Finck static int strcmp_wa(const WCHAR *strw, const char *stra)
88c2c66affSColin Finck {
89c2c66affSColin Finck     WCHAR buf[512];
9011d1bab6SAmine Khaldi     MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
91c2c66affSColin Finck     return lstrcmpW(strw, buf);
92c2c66affSColin Finck }
93c2c66affSColin Finck 
a2w(const char * str)94c2c66affSColin Finck static WCHAR *a2w(const char *str)
95c2c66affSColin Finck {
96c2c66affSColin Finck     WCHAR *ret;
97c2c66affSColin Finck     int len;
98c2c66affSColin Finck 
99c2c66affSColin Finck     if(!str)
100c2c66affSColin Finck         return NULL;
101c2c66affSColin Finck 
102c2c66affSColin Finck     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
103c2c66affSColin Finck     ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
104c2c66affSColin Finck     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
105c2c66affSColin Finck 
106c2c66affSColin Finck     return ret;
107c2c66affSColin Finck }
108c2c66affSColin Finck 
a2co(const char * str)109eb91a739SAmine Khaldi static WCHAR *a2co(const char *str)
110eb91a739SAmine Khaldi {
111eb91a739SAmine Khaldi     WCHAR *ret;
112eb91a739SAmine Khaldi     int len;
113eb91a739SAmine Khaldi 
114eb91a739SAmine Khaldi     if(!str)
115eb91a739SAmine Khaldi         return NULL;
116eb91a739SAmine Khaldi 
117eb91a739SAmine Khaldi     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
118eb91a739SAmine Khaldi     ret = CoTaskMemAlloc(len*sizeof(WCHAR));
119eb91a739SAmine Khaldi     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
120eb91a739SAmine Khaldi 
121eb91a739SAmine Khaldi     return ret;
122eb91a739SAmine Khaldi }
123eb91a739SAmine Khaldi 
test_CreateFormatEnum(void)124c2c66affSColin Finck static void test_CreateFormatEnum(void)
125c2c66affSColin Finck {
126c2c66affSColin Finck     IEnumFORMATETC *fenum = NULL, *fenum2 = NULL;
127c2c66affSColin Finck     FORMATETC fetc[5];
128c2c66affSColin Finck     ULONG ul;
129c2c66affSColin Finck     HRESULT hres;
130c2c66affSColin Finck 
131c2c66affSColin Finck     static DVTARGETDEVICE dev = {sizeof(dev),0,0,0,0,{0}};
132c2c66affSColin Finck     static FORMATETC formatetc[] = {
133c2c66affSColin Finck         {0,&dev,0,0,0},
134c2c66affSColin Finck         {0,&dev,0,1,0},
135c2c66affSColin Finck         {0,NULL,0,2,0},
136c2c66affSColin Finck         {0,NULL,0,3,0},
137c2c66affSColin Finck         {0,NULL,0,4,0}
138c2c66affSColin Finck     };
139c2c66affSColin Finck 
140c2c66affSColin Finck     hres = CreateFormatEnumerator(0, formatetc, &fenum);
141c2c66affSColin Finck     ok(hres == E_FAIL, "CreateFormatEnumerator failed: %08x, expected E_FAIL\n", hres);
142c2c66affSColin Finck     hres = CreateFormatEnumerator(0, formatetc, NULL);
143c2c66affSColin Finck     ok(hres == E_INVALIDARG, "CreateFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
144c2c66affSColin Finck     hres = CreateFormatEnumerator(5, formatetc, NULL);
145c2c66affSColin Finck     ok(hres == E_INVALIDARG, "CreateFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
146c2c66affSColin Finck 
147c2c66affSColin Finck 
148c2c66affSColin Finck     hres = CreateFormatEnumerator(5, formatetc, &fenum);
149c2c66affSColin Finck     ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
150c2c66affSColin Finck     if(FAILED(hres))
151c2c66affSColin Finck         return;
152c2c66affSColin Finck 
153c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 2, NULL, &ul);
154c2c66affSColin Finck     ok(hres == E_INVALIDARG, "Next failed: %08x, expected E_INVALIDARG\n", hres);
155c2c66affSColin Finck     ul = 100;
156c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 0, fetc, &ul);
157c2c66affSColin Finck     ok(hres == S_OK, "Next failed: %08x\n", hres);
158c2c66affSColin Finck     ok(ul == 0, "ul=%d, expected 0\n", ul);
159c2c66affSColin Finck 
160c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 2, fetc, &ul);
161c2c66affSColin Finck     ok(hres == S_OK, "Next failed: %08x\n", hres);
162c2c66affSColin Finck     ok(fetc[0].lindex == 0, "fetc[0].lindex=%d, expected 0\n", fetc[0].lindex);
163c2c66affSColin Finck     ok(fetc[1].lindex == 1, "fetc[1].lindex=%d, expected 1\n", fetc[1].lindex);
164c2c66affSColin Finck     ok(fetc[0].ptd == &dev, "fetc[0].ptd=%p, expected %p\n", fetc[0].ptd, &dev);
165c2c66affSColin Finck     ok(ul == 2, "ul=%d, expected 2\n", ul);
166c2c66affSColin Finck 
167c2c66affSColin Finck     hres = IEnumFORMATETC_Skip(fenum, 1);
168c2c66affSColin Finck     ok(hres == S_OK, "Skip failed: %08x\n", hres);
169c2c66affSColin Finck 
170c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 4, fetc, &ul);
171c2c66affSColin Finck     ok(hres == S_FALSE, "Next failed: %08x, expected S_FALSE\n", hres);
172c2c66affSColin Finck     ok(fetc[0].lindex == 3, "fetc[0].lindex=%d, expected 3\n", fetc[0].lindex);
173c2c66affSColin Finck     ok(fetc[1].lindex == 4, "fetc[1].lindex=%d, expected 4\n", fetc[1].lindex);
174c2c66affSColin Finck     ok(fetc[0].ptd == NULL, "fetc[0].ptd=%p, expected NULL\n", fetc[0].ptd);
175c2c66affSColin Finck     ok(ul == 2, "ul=%d, expected 2\n", ul);
176c2c66affSColin Finck 
177c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 4, fetc, &ul);
178c2c66affSColin Finck     ok(hres == S_FALSE, "Next failed: %08x, expected S_FALSE\n", hres);
179c2c66affSColin Finck     ok(ul == 0, "ul=%d, expected 0\n", ul);
180c2c66affSColin Finck     ul = 100;
181c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 0, fetc, &ul);
182c2c66affSColin Finck     ok(hres == S_OK, "Next failed: %08x\n", hres);
183c2c66affSColin Finck     ok(ul == 0, "ul=%d, expected 0\n", ul);
184c2c66affSColin Finck 
185c2c66affSColin Finck     hres = IEnumFORMATETC_Skip(fenum, 3);
186c2c66affSColin Finck     ok(hres == S_FALSE, "Skip failed: %08x, expected S_FALSE\n", hres);
187c2c66affSColin Finck 
188c2c66affSColin Finck     hres = IEnumFORMATETC_Reset(fenum);
189c2c66affSColin Finck     ok(hres == S_OK, "Reset failed: %08x\n", hres);
190c2c66affSColin Finck 
191c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 5, fetc, NULL);
192c2c66affSColin Finck     ok(hres == S_OK, "Next failed: %08x\n", hres);
193c2c66affSColin Finck     ok(fetc[0].lindex == 0, "fetc[0].lindex=%d, expected 0\n", fetc[0].lindex);
194c2c66affSColin Finck 
195c2c66affSColin Finck     hres = IEnumFORMATETC_Reset(fenum);
196c2c66affSColin Finck     ok(hres == S_OK, "Reset failed: %08x\n", hres);
197c2c66affSColin Finck 
198c2c66affSColin Finck     hres = IEnumFORMATETC_Skip(fenum, 2);
199c2c66affSColin Finck     ok(hres == S_OK, "Skip failed: %08x\n", hres);
200c2c66affSColin Finck 
201c2c66affSColin Finck     hres = IEnumFORMATETC_Clone(fenum, NULL);
202c2c66affSColin Finck     ok(hres == E_INVALIDARG, "Clone failed: %08x, expected E_INVALIDARG\n", hres);
203c2c66affSColin Finck 
204c2c66affSColin Finck     hres = IEnumFORMATETC_Clone(fenum, &fenum2);
205c2c66affSColin Finck     ok(hres == S_OK, "Clone failed: %08x\n", hres);
206c2c66affSColin Finck 
207c2c66affSColin Finck     if(SUCCEEDED(hres)) {
208c2c66affSColin Finck         ok(fenum != fenum2, "fenum == fenum2\n");
209c2c66affSColin Finck 
210c2c66affSColin Finck         hres = IEnumFORMATETC_Next(fenum2, 2, fetc, &ul);
211c2c66affSColin Finck         ok(hres == S_OK, "Next failed: %08x\n", hres);
212c2c66affSColin Finck         ok(fetc[0].lindex == 2, "fetc[0].lindex=%d, expected 2\n", fetc[0].lindex);
213c2c66affSColin Finck 
214c2c66affSColin Finck         IEnumFORMATETC_Release(fenum2);
215c2c66affSColin Finck     }
216c2c66affSColin Finck 
217c2c66affSColin Finck     hres = IEnumFORMATETC_Next(fenum, 2, fetc, &ul);
218c2c66affSColin Finck     ok(hres == S_OK, "Next failed: %08x\n", hres);
219c2c66affSColin Finck     ok(fetc[0].lindex == 2, "fetc[0].lindex=%d, expected 2\n", fetc[0].lindex);
220c2c66affSColin Finck 
221c2c66affSColin Finck     hres = IEnumFORMATETC_Skip(fenum, 1);
222c2c66affSColin Finck     ok(hres == S_OK, "Skip failed: %08x\n", hres);
223c2c66affSColin Finck 
224c2c66affSColin Finck     IEnumFORMATETC_Release(fenum);
225c2c66affSColin Finck }
226c2c66affSColin Finck 
test_RegisterFormatEnumerator(void)227c2c66affSColin Finck static void test_RegisterFormatEnumerator(void)
228c2c66affSColin Finck {
229c2c66affSColin Finck     IBindCtx *bctx = NULL;
230c2c66affSColin Finck     IEnumFORMATETC *format = NULL, *format2 = NULL;
231c2c66affSColin Finck     IUnknown *unk = NULL;
232c2c66affSColin Finck     HRESULT hres;
233c2c66affSColin Finck 
234c2c66affSColin Finck     static FORMATETC formatetc = {0,NULL,0,0,0};
235c2c66affSColin Finck     static WCHAR wszEnumFORMATETC[] =
236c2c66affSColin Finck         {'_','E','n','u','m','F','O','R','M','A','T','E','T','C','_',0};
237c2c66affSColin Finck 
238c2c66affSColin Finck     CreateBindCtx(0, &bctx);
239c2c66affSColin Finck 
240c2c66affSColin Finck     hres = CreateFormatEnumerator(1, &formatetc, &format);
241c2c66affSColin Finck     ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
242c2c66affSColin Finck     if(FAILED(hres))
243c2c66affSColin Finck         return;
244c2c66affSColin Finck 
245c2c66affSColin Finck     hres = RegisterFormatEnumerator(NULL, format, 0);
246c2c66affSColin Finck     ok(hres == E_INVALIDARG,
247c2c66affSColin Finck             "RegisterFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
248c2c66affSColin Finck     hres = RegisterFormatEnumerator(bctx, NULL, 0);
249c2c66affSColin Finck     ok(hres == E_INVALIDARG,
250c2c66affSColin Finck             "RegisterFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
251c2c66affSColin Finck 
252c2c66affSColin Finck     hres = RegisterFormatEnumerator(bctx, format, 0);
253c2c66affSColin Finck     ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
254c2c66affSColin Finck 
255c2c66affSColin Finck     hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
256c2c66affSColin Finck     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
257c2c66affSColin Finck     ok(unk == (IUnknown*)format, "unk != format\n");
258c2c66affSColin Finck 
259c2c66affSColin Finck     hres = RevokeFormatEnumerator(NULL, format);
260c2c66affSColin Finck     ok(hres == E_INVALIDARG,
261c2c66affSColin Finck             "RevokeFormatEnumerator failed: %08x, expected E_INVALIDARG\n", hres);
262c2c66affSColin Finck 
263c2c66affSColin Finck     hres = RevokeFormatEnumerator(bctx, format);
264c2c66affSColin Finck     ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
265c2c66affSColin Finck 
266c2c66affSColin Finck     hres = RevokeFormatEnumerator(bctx, format);
267c2c66affSColin Finck     ok(hres == E_FAIL, "RevokeFormatEnumerator failed: %08x, expected E_FAIL\n", hres);
268c2c66affSColin Finck 
269c2c66affSColin Finck     hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
270c2c66affSColin Finck     ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
271c2c66affSColin Finck 
272c2c66affSColin Finck     hres = RegisterFormatEnumerator(bctx, format, 0);
273c2c66affSColin Finck     ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
274c2c66affSColin Finck 
275c2c66affSColin Finck     hres = CreateFormatEnumerator(1, &formatetc, &format2);
276c2c66affSColin Finck     ok(hres == S_OK, "CreateFormatEnumerator failed: %08x\n", hres);
277c2c66affSColin Finck 
278c2c66affSColin Finck     if(SUCCEEDED(hres)) {
279c2c66affSColin Finck         hres = RevokeFormatEnumerator(bctx, format);
280c2c66affSColin Finck         ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
281c2c66affSColin Finck 
282c2c66affSColin Finck         IEnumFORMATETC_Release(format2);
283c2c66affSColin Finck     }
284c2c66affSColin Finck 
285c2c66affSColin Finck     hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
286c2c66affSColin Finck     ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
287c2c66affSColin Finck 
288c2c66affSColin Finck     IEnumFORMATETC_Release(format);
289c2c66affSColin Finck 
290c2c66affSColin Finck     hres = RegisterFormatEnumerator(bctx, format, 0);
291c2c66affSColin Finck     ok(hres == S_OK, "RegisterFormatEnumerator failed: %08x\n", hres);
292c2c66affSColin Finck     hres = RevokeFormatEnumerator(bctx, NULL);
293c2c66affSColin Finck     ok(hres == S_OK, "RevokeFormatEnumerator failed: %08x\n", hres);
294c2c66affSColin Finck     hres = IBindCtx_GetObjectParam(bctx, wszEnumFORMATETC, &unk);
295c2c66affSColin Finck     ok(hres == E_FAIL, "GetObjectParam failed: %08x, expected E_FAIL\n", hres);
296c2c66affSColin Finck 
297c2c66affSColin Finck     IEnumFORMATETC_Release(format);
298c2c66affSColin Finck     IBindCtx_Release(bctx);
299c2c66affSColin Finck }
300c2c66affSColin Finck static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l',
301c2c66affSColin Finck         '/','b','l','a','n','k','.','h','t','m',0};
302c2c66affSColin Finck static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
303c2c66affSColin Finck static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0};
304c2c66affSColin Finck static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
305c2c66affSColin Finck         '%','2','e','j','p','g',0};
306c2c66affSColin Finck static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
307c2c66affSColin Finck         '.','o','r','g',0};
308c2c66affSColin Finck static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
309c2c66affSColin Finck static const WCHAR url7[] = {'f','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',
310c2c66affSColin Finck         'f','i','l','e','.','t','e','s','t',0};
311c2c66affSColin Finck static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0};
312c2c66affSColin Finck static const WCHAR url9[] =
313c2c66affSColin Finck     {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',
314c2c66affSColin Finck      '/','s','i','t','e','/','a','b','o','u','t',0};
315c2c66affSColin Finck static const WCHAR url10[] = {'h','t','t','p',':','/','/','g','o','o','g','l','e','.','*','.',
316c2c66affSColin Finck         'c','o','m',0};
317c2c66affSColin Finck static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
318c2c66affSColin Finck         '.','j','p','g',0};
319c2c66affSColin Finck 
320c2c66affSColin Finck static const WCHAR path3[] = {'c',':','\\','I','n','d','e','x','.','h','t','m',0};
321c2c66affSColin Finck static const WCHAR path4[] = {'s','o','m','e',' ','f','i','l','e','.','j','p','g',0};
322c2c66affSColin Finck 
323c2c66affSColin Finck static const WCHAR wszRes[] = {'r','e','s',0};
324c2c66affSColin Finck static const WCHAR wszFile[] = {'f','i','l','e',0};
325c2c66affSColin Finck static const WCHAR wszHttp[] = {'h','t','t','p',0};
326c2c66affSColin Finck static const WCHAR wszAbout[] = {'a','b','o','u','t',0};
327c2c66affSColin Finck static const WCHAR wszEmpty[] = {0};
328c2c66affSColin Finck static const WCHAR wszGoogle[] = {'g','o','o','g','l','e','.','*','.','c','o','m',0};
329c2c66affSColin Finck 
330c2c66affSColin Finck static const WCHAR wszWineHQ[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
331c2c66affSColin Finck static const WCHAR wszHttpWineHQ[] = {'h','t','t','p',':','/','/','w','w','w','.',
332c2c66affSColin Finck     'w','i','n','e','h','q','.','o','r','g',0};
333c2c66affSColin Finck static const WCHAR wszHttpGoogle[] = {'h','t','t','p',':','/','/','g','o','o','g','l','e',
334c2c66affSColin Finck     '.','*','.','c','o','m',0};
335c2c66affSColin Finck 
336c2c66affSColin Finck struct parse_test {
337c2c66affSColin Finck     LPCWSTR url;
338c2c66affSColin Finck     HRESULT secur_hres;
339c2c66affSColin Finck     LPCWSTR encoded_url;
340c2c66affSColin Finck     HRESULT path_hres;
341c2c66affSColin Finck     LPCWSTR path;
342c2c66affSColin Finck     LPCWSTR schema;
343c2c66affSColin Finck     LPCWSTR domain;
344c2c66affSColin Finck     HRESULT domain_hres;
345c2c66affSColin Finck     LPCWSTR rootdocument;
346c2c66affSColin Finck     HRESULT rootdocument_hres;
347c2c66affSColin Finck };
348c2c66affSColin Finck 
349c2c66affSColin Finck static const struct parse_test parse_tests[] = {
350c2c66affSColin Finck     {url1, S_OK,   url1,  E_INVALIDARG, NULL, wszRes, NULL, E_FAIL, NULL, E_FAIL},
351c2c66affSColin Finck     {url2, E_FAIL, url2,  E_INVALIDARG, NULL, wszEmpty, NULL, E_FAIL, NULL, E_FAIL},
352c2c66affSColin Finck     {url3, E_FAIL, url3,  S_OK, path3,        wszFile, wszEmpty, S_OK, NULL, E_FAIL},
353c2c66affSColin Finck     {url4, E_FAIL, url4e, S_OK, path4,        wszFile, wszEmpty, S_OK, NULL, E_FAIL},
354c2c66affSColin Finck     {url5, E_FAIL, url5,  E_INVALIDARG, NULL, wszHttp, wszWineHQ, S_OK, wszHttpWineHQ, S_OK},
355c2c66affSColin Finck     {url6, S_OK,   url6,  E_INVALIDARG, NULL, wszAbout, NULL, E_FAIL, NULL, E_FAIL},
356c2c66affSColin Finck     {url10, E_FAIL, url10, E_INVALIDARG,NULL, wszHttp, wszGoogle, S_OK, wszHttpGoogle, S_OK}
357c2c66affSColin Finck };
358c2c66affSColin Finck 
test_CoInternetParseUrl(void)359c2c66affSColin Finck static void test_CoInternetParseUrl(void)
360c2c66affSColin Finck {
361c2c66affSColin Finck     HRESULT hres;
362c2c66affSColin Finck     DWORD size;
363c2c66affSColin Finck     int i;
364c2c66affSColin Finck 
365c2c66affSColin Finck     static WCHAR buf[4096];
366c2c66affSColin Finck 
367c2c66affSColin Finck     memset(buf, 0xf0, sizeof(buf));
368c2c66affSColin Finck     hres = pCoInternetParseUrl(parse_tests[0].url, PARSE_SCHEMA, 0, buf,
369c2c66affSColin Finck             3, &size, 0);
370c2c66affSColin Finck     ok(hres == E_POINTER, "schema failed: %08x, expected E_POINTER\n", hres);
371c2c66affSColin Finck 
37211d1bab6SAmine Khaldi     for(i = 0; i < ARRAY_SIZE(parse_tests); i++) {
373c2c66affSColin Finck         memset(buf, 0xf0, sizeof(buf));
374c2c66affSColin Finck         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_SECURITY_URL, 0, buf,
37511d1bab6SAmine Khaldi                 ARRAY_SIZE(buf), &size, 0);
376c2c66affSColin Finck         ok(hres == parse_tests[i].secur_hres, "[%d] security url failed: %08x, expected %08x\n",
377c2c66affSColin Finck                 i, hres, parse_tests[i].secur_hres);
378c2c66affSColin Finck 
379c2c66affSColin Finck         memset(buf, 0xf0, sizeof(buf));
380c2c66affSColin Finck         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_ENCODE, 0, buf,
38111d1bab6SAmine Khaldi                 ARRAY_SIZE(buf), &size, 0);
382c2c66affSColin Finck         ok(hres == S_OK, "[%d] encoding failed: %08x\n", i, hres);
383c2c66affSColin Finck         ok(size == lstrlenW(parse_tests[i].encoded_url), "[%d] wrong size\n", i);
384c2c66affSColin Finck         ok(!lstrcmpW(parse_tests[i].encoded_url, buf), "[%d] wrong encoded url\n", i);
385c2c66affSColin Finck 
386c2c66affSColin Finck         memset(buf, 0xf0, sizeof(buf));
387*98e4a3ecSAmine Khaldi         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_UNESCAPE, 0, buf,
388*98e4a3ecSAmine Khaldi                 ARRAY_SIZE(buf), &size, 0);
389*98e4a3ecSAmine Khaldi         ok(hres == S_OK, "[%d] encoding failed: %08x\n", i, hres);
390*98e4a3ecSAmine Khaldi         ok(size == lstrlenW(parse_tests[i].encoded_url), "[%d] wrong size\n", i);
391*98e4a3ecSAmine Khaldi         ok(!lstrcmpW(parse_tests[i].encoded_url, buf), "[%d] wrong encoded url\n", i);
392*98e4a3ecSAmine Khaldi 
393*98e4a3ecSAmine Khaldi         memset(buf, 0xf0, sizeof(buf));
394c2c66affSColin Finck         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_PATH_FROM_URL, 0, buf,
39511d1bab6SAmine Khaldi                 ARRAY_SIZE(buf), &size, 0);
396c2c66affSColin Finck         ok(hres == parse_tests[i].path_hres, "[%d] path failed: %08x, expected %08x\n",
397c2c66affSColin Finck                 i, hres, parse_tests[i].path_hres);
398c2c66affSColin Finck         if(parse_tests[i].path) {
399c2c66affSColin Finck             ok(size == lstrlenW(parse_tests[i].path), "[%d] wrong size\n", i);
400c2c66affSColin Finck             ok(!lstrcmpW(parse_tests[i].path, buf), "[%d] wrong path\n", i);
401c2c66affSColin Finck         }
402c2c66affSColin Finck 
403c2c66affSColin Finck         memset(buf, 0xf0, sizeof(buf));
404c2c66affSColin Finck         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_SCHEMA, 0, buf,
40511d1bab6SAmine Khaldi                 ARRAY_SIZE(buf), &size, 0);
406c2c66affSColin Finck         ok(hres == S_OK, "[%d] schema failed: %08x\n", i, hres);
407c2c66affSColin Finck         ok(size == lstrlenW(parse_tests[i].schema), "[%d] wrong size\n", i);
408c2c66affSColin Finck         ok(!lstrcmpW(parse_tests[i].schema, buf), "[%d] wrong schema\n", i);
409c2c66affSColin Finck 
410c2c66affSColin Finck         if(memcmp(parse_tests[i].url, wszRes, 3*sizeof(WCHAR))
411c2c66affSColin Finck                 && memcmp(parse_tests[i].url, wszAbout, 5*sizeof(WCHAR))) {
412c2c66affSColin Finck             memset(buf, 0xf0, sizeof(buf));
413c2c66affSColin Finck             hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_DOMAIN, 0, buf,
41411d1bab6SAmine Khaldi                     ARRAY_SIZE(buf), &size, 0);
415c2c66affSColin Finck             ok(hres == parse_tests[i].domain_hres, "[%d] domain failed: %08x\n", i, hres);
416c2c66affSColin Finck             if(parse_tests[i].domain)
417c2c66affSColin Finck                 ok(!lstrcmpW(parse_tests[i].domain, buf), "[%d] wrong domain, received %s\n", i, wine_dbgstr_w(buf));
418c2c66affSColin Finck         }
419c2c66affSColin Finck 
420c2c66affSColin Finck         memset(buf, 0xf0, sizeof(buf));
421c2c66affSColin Finck         hres = pCoInternetParseUrl(parse_tests[i].url, PARSE_ROOTDOCUMENT, 0, buf,
42211d1bab6SAmine Khaldi                 ARRAY_SIZE(buf), &size, 0);
423c2c66affSColin Finck         ok(hres == parse_tests[i].rootdocument_hres, "[%d] rootdocument failed: %08x\n", i, hres);
424c2c66affSColin Finck         if(parse_tests[i].rootdocument)
425c2c66affSColin Finck             ok(!lstrcmpW(parse_tests[i].rootdocument, buf), "[%d] wrong rootdocument, received %s\n", i, wine_dbgstr_w(buf));
426c2c66affSColin Finck     }
427c2c66affSColin Finck }
428c2c66affSColin Finck 
test_CoInternetCompareUrl(void)429c2c66affSColin Finck static void test_CoInternetCompareUrl(void)
430c2c66affSColin Finck {
431c2c66affSColin Finck     HRESULT hres;
432c2c66affSColin Finck 
433c2c66affSColin Finck     hres = pCoInternetCompareUrl(url1, url1, 0);
434c2c66affSColin Finck     ok(hres == S_OK, "CoInternetCompareUrl failed: %08x\n", hres);
435c2c66affSColin Finck 
436c2c66affSColin Finck     hres = pCoInternetCompareUrl(url1, url3, 0);
437c2c66affSColin Finck     ok(hres == S_FALSE, "CoInternetCompareUrl failed: %08x\n", hres);
438c2c66affSColin Finck 
439c2c66affSColin Finck     hres = pCoInternetCompareUrl(url3, url1, 0);
440c2c66affSColin Finck     ok(hres == S_FALSE, "CoInternetCompareUrl failed: %08x\n", hres);
441c2c66affSColin Finck }
442c2c66affSColin Finck 
443c2c66affSColin Finck static const struct {
444c2c66affSColin Finck     LPCWSTR url;
445c2c66affSColin Finck     DWORD uses_net;
446c2c66affSColin Finck } query_info_tests[] = {
447c2c66affSColin Finck     {url1, 0},
448c2c66affSColin Finck     {url2, 0},
449c2c66affSColin Finck     {url3, 0},
450c2c66affSColin Finck     {url4, 0},
451c2c66affSColin Finck     {url5, 0},
452c2c66affSColin Finck     {url6, 0},
453c2c66affSColin Finck     {url7, 0},
454c2c66affSColin Finck     {url8, 0}
455c2c66affSColin Finck };
456c2c66affSColin Finck 
test_CoInternetQueryInfo(void)457c2c66affSColin Finck static void test_CoInternetQueryInfo(void)
458c2c66affSColin Finck {
459c2c66affSColin Finck     BYTE buf[100];
460c2c66affSColin Finck     DWORD cb, i;
461c2c66affSColin Finck     HRESULT hres;
462c2c66affSColin Finck 
46311d1bab6SAmine Khaldi     for(i = 0; i < ARRAY_SIZE(query_info_tests); i++) {
464c2c66affSColin Finck         cb = 0xdeadbeef;
465c2c66affSColin Finck         memset(buf, '?', sizeof(buf));
466c2c66affSColin Finck         hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), &cb, 0);
467c2c66affSColin Finck         ok(hres == S_OK, "[%d] CoInternetQueryInfo failed: %08x\n", i, hres);
468c2c66affSColin Finck         ok(cb == sizeof(DWORD), "[%d] cb = %d\n", i, cb);
469c2c66affSColin Finck         ok(*(DWORD*)buf == query_info_tests[i].uses_net, "[%d] ret %x, expected %x\n",
470c2c66affSColin Finck            i, *(DWORD*)buf, query_info_tests[i].uses_net);
471c2c66affSColin Finck 
472c2c66affSColin Finck         hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, 3, &cb, 0);
473c2c66affSColin Finck         ok(hres == E_FAIL, "[%d] CoInternetQueryInfo failed: %08x, expected E_FAIL\n", i, hres);
474c2c66affSColin Finck         hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, NULL, sizeof(buf), &cb, 0);
475c2c66affSColin Finck         ok(hres == E_FAIL, "[%d] CoInternetQueryInfo failed: %08x, expected E_FAIL\n", i, hres);
476c2c66affSColin Finck 
477c2c66affSColin Finck         memset(buf, '?', sizeof(buf));
478c2c66affSColin Finck         hres = pCoInternetQueryInfo(query_info_tests[0].url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), NULL, 0);
479c2c66affSColin Finck         ok(hres == S_OK, "[%d] CoInternetQueryInfo failed: %08x\n", i, hres);
480c2c66affSColin Finck         ok(*(DWORD*)buf == query_info_tests[i].uses_net, "[%d] ret %x, expected %x\n",
481c2c66affSColin Finck            i, *(DWORD*)buf, query_info_tests[i].uses_net);
482c2c66affSColin Finck     }
483c2c66affSColin Finck }
484c2c66affSColin Finck 
485c2c66affSColin Finck static const struct {
486c2c66affSColin Finck     const char *url;
487c2c66affSColin Finck     const char *mime;
488c2c66affSColin Finck     HRESULT hres;
489c2c66affSColin Finck     BOOL broken_failure;
490c2c66affSColin Finck     const char *broken_mime;
491c2c66affSColin Finck } mime_tests[] = {
492c2c66affSColin Finck     {"res://mshtml.dll/blank.htm", "text/html", S_OK},
493c2c66affSColin Finck     {"index.htm", "text/html", S_OK},
494c2c66affSColin Finck     {"file://c:\\Index.htm", "text/html", S_OK},
495c2c66affSColin Finck     {"file://c:\\Index.htm?q=test", "text/html", S_OK, TRUE},
496c2c66affSColin Finck     {"file://c:\\Index.htm#hash_part", "text/html", S_OK, TRUE},
497c2c66affSColin Finck     {"file://c:\\Index.htm#hash_part.txt", "text/html", S_OK, FALSE, "text/plain"},
498c2c66affSColin Finck     {"file://some%20file%2ejpg", NULL, E_FAIL},
499c2c66affSColin Finck     {"http://www.winehq.org", NULL, __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)},
500c2c66affSColin Finck     {"about:blank", NULL, E_FAIL},
501c2c66affSColin Finck     {"ftp://winehq.org/file.test", NULL, __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)}
502c2c66affSColin Finck };
503c2c66affSColin Finck 
504c2c66affSColin Finck static BYTE data1[] = "test data\n";
505c2c66affSColin Finck static BYTE data2[] = {31,'t','e','s',0xfa,'t',' ','d','a','t','a','\n',0};
506c2c66affSColin Finck static BYTE data3[] = {0,0,0};
507c2c66affSColin Finck static BYTE data4[] = {'t','e','s',0xfa,'t',' ','d','a','t','a','\n',0,0};
508c2c66affSColin Finck static BYTE data5[] = {0xa,0xa,0xa,'x',32,'x',0};
509c2c66affSColin Finck static BYTE data6[] = {0xfa,0xfa,0xfa,0xfa,'\n','\r','\t','x','x','x',1};
510c2c66affSColin Finck static BYTE data7[] = "<html>blahblah";
511c2c66affSColin Finck static BYTE data8[] = {'t','e','s',0xfa,'t',' ','<','h','t','m','l','>','d','a','t','a','\n',0,0};
512c2c66affSColin Finck static BYTE data9[] = {'t','e',0,'s',0xfa,'t',' ','<','h','t','m','l','>','d','a','t','a','\n',0,0};
513c2c66affSColin Finck static BYTE data10[] = "<HtmL>blahblah";
514c2c66affSColin Finck static BYTE data11[] = "blah<HTML>blahblah";
515c2c66affSColin Finck static BYTE data12[] = "blah<HTMLblahblah";
516c2c66affSColin Finck static BYTE data13[] = "blahHTML>blahblah";
517c2c66affSColin Finck static BYTE data14[] = "blah<HTMblahblah";
518c2c66affSColin Finck static BYTE data15[] = {0xff,0xd8};
519c2c66affSColin Finck static BYTE data16[] = {0xff,0xd8,'h'};
520c2c66affSColin Finck static BYTE data17[] = {0,0xff,0xd8};
521c2c66affSColin Finck static BYTE data18[] = {0xff,0xd8,'<','h','t','m','l','>'};
522c2c66affSColin Finck static BYTE data19[] = {'G','I','F','8','7','a'};
523c2c66affSColin Finck static BYTE data20[] = {'G','I','F','8','9','a'};
524c2c66affSColin Finck static BYTE data21[] = {'G','I','F','8','7'};
525c2c66affSColin Finck static BYTE data22[] = {'G','i','F','8','7','a'};
526c2c66affSColin Finck static BYTE data23[] = {'G','i','F','8','8','a'};
527c2c66affSColin Finck static BYTE data24[] = {'g','i','f','8','7','a'};
528c2c66affSColin Finck static BYTE data25[] = {'G','i','F','8','7','A'};
529c2c66affSColin Finck static BYTE data26[] = {'G','i','F','8','7','a','<','h','t','m','l','>'};
530c2c66affSColin Finck static BYTE data27[] = {0x30,'G','i','F','8','7','A'};
531c2c66affSColin Finck static BYTE data28[] = {0x42,0x4d,0x6e,0x42,0x1c,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00};
532c2c66affSColin Finck static BYTE data29[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x','x'};
533c2c66affSColin Finck static BYTE data30[] = {0x42,0x4d,'x','x','x','x',0x00,0x01,0x00,0x00,'x','x','x','x'};
534c2c66affSColin Finck static BYTE data31[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'<','h','t','m','l','>'};
535c2c66affSColin Finck static BYTE data32[] = {0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x'};
536c2c66affSColin Finck static BYTE data33[] = {0x00,0x42,0x4d,'x','x','x','x',0x00,0x00,0x00,0x00,'x','x','x'};
537c2c66affSColin Finck static BYTE data34[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x'};
538c2c66affSColin Finck static BYTE data35[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x','x','x','x',0};
539c2c66affSColin Finck static BYTE data36[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,'x','x'};
540c2c66affSColin Finck static BYTE data37[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'<','h','t','m','l','>'};
541c2c66affSColin Finck static BYTE data38[] = {0x00,0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x'};
542c2c66affSColin Finck static BYTE data39[] = {0x4d,0x4d,0x00,0x2a,0xff};
543c2c66affSColin Finck static BYTE data40[] = {0x4d,0x4d,0x00,0x2a,'<','h','t','m','l','>',0};
544c2c66affSColin Finck static BYTE data41[] = {0x4d,0x4d,0xff};
545c2c66affSColin Finck static BYTE data42[] = {0x4d,0x4d};
546c2c66affSColin Finck static BYTE data43[] = {0x00,0x4d,0x4d,0x00};
547c2c66affSColin Finck static BYTE data44[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20,0xff};
548c2c66affSColin Finck static BYTE data45[] = {'R','I','F','f',0xff,0xff,0xff,0xff,'A','V','I',0x20,0xff};
549c2c66affSColin Finck static BYTE data46[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20};
550c2c66affSColin Finck static BYTE data47[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x21,0xff};
551c2c66affSColin Finck static BYTE data48[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'A','V','I',0x20,'<','h','t','m','l','>'};
552c2c66affSColin Finck static BYTE data49[] = {'R','I','F','F',0x0f,0x0f,0xf0,0xf0,'A','V','I',0x20,0xf0,0x00};
553c2c66affSColin Finck static BYTE data50[] = {0x00,0x00,0x01,0xb3,0xff};
554c2c66affSColin Finck static BYTE data51[] = {0x00,0x00,0x01,0xba,0xff};
555c2c66affSColin Finck static BYTE data52[] = {0x00,0x00,0x01,0xb8,0xff};
556c2c66affSColin Finck static BYTE data53[] = {0x00,0x00,0x01,0xba};
557c2c66affSColin Finck static BYTE data54[] = {0x00,0x00,0x01,0xba,'<','h','t','m','l','>'};
558c2c66affSColin Finck static BYTE data55[] = {0x1f,0x8b,'x'};
559c2c66affSColin Finck static BYTE data56[] = {0x1f};
560c2c66affSColin Finck static BYTE data57[] = {0x1f,0x8b,'<','h','t','m','l','>','t','e','s','t',0};
561c2c66affSColin Finck static BYTE data58[] = {0x1f,0x8b};
562c2c66affSColin Finck static BYTE data59[] = {0x50,0x4b,'x'};
563c2c66affSColin Finck static BYTE data60[] = {0x50,0x4b};
564c2c66affSColin Finck static BYTE data61[] = {0x50,0x4b,'<','h','t','m','l','>',0};
565c2c66affSColin Finck static BYTE data62[] = {0xca,0xfe,0xba,0xbe,'x'};
566c2c66affSColin Finck static BYTE data63[] = {0xca,0xfe,0xba,0xbe};
567c2c66affSColin Finck static BYTE data64[] = {0xca,0xfe,0xba,0xbe,'<','h','t','m','l','>',0};
568c2c66affSColin Finck static BYTE data65[] = {0x25,0x50,0x44,0x46,'x'};
569c2c66affSColin Finck static BYTE data66[] = {0x25,0x50,0x44,0x46};
570c2c66affSColin Finck static BYTE data67[] = {0x25,0x50,0x44,0x46,'x','<','h','t','m','l','>'};
571c2c66affSColin Finck static BYTE data68[] = {'M','Z','x'};
572c2c66affSColin Finck static BYTE data69[] = {'M','Z'};
573c2c66affSColin Finck static BYTE data70[] = {'M','Z','<','h','t','m','l','>',0xff};
574c2c66affSColin Finck static BYTE data71[] = {'{','\\','r','t','f',0};
575c2c66affSColin Finck static BYTE data72[] = {'{','\\','r','t','f'};
576c2c66affSColin Finck static BYTE data73[] = {' ','{','\\','r','t','f',' '};
577c2c66affSColin Finck static BYTE data74[] = {'{','\\','r','t','f','<','h','t','m','l','>',' '};
578c2c66affSColin Finck static BYTE data75[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V','E',0xff};
579c2c66affSColin Finck static BYTE data76[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V','E'};
580c2c66affSColin Finck static BYTE data77[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V',0xff,0xff};
581c2c66affSColin Finck static BYTE data78[] = {'R','I','F','F',0xff,0xff,0xff,0xff,'<','h','t','m','l','>',0xff};
582c2c66affSColin Finck static BYTE data79[] = {'%','!',0xff};
583c2c66affSColin Finck static BYTE data80[] = {'%','!'};
584c2c66affSColin Finck static BYTE data81[] = {'%','!','P','S','<','h','t','m','l','>'};
585c2c66affSColin Finck static BYTE data82[] = {'.','s','n','d',0};
586c2c66affSColin Finck static BYTE data83[] = {'.','s','n','d'};
587c2c66affSColin Finck static BYTE data84[] = {'.','s','n','d',0,'<','h','t','m','l','>',1,1};
588c2c66affSColin Finck static BYTE data85[] = {'.','S','N','D',0};
589c2c66affSColin Finck static BYTE data86[] = {0x49,0x49,0x2a,0xff};
590c2c66affSColin Finck static BYTE data87[] = {' ','<','h','e','a','d'};
591c2c66affSColin Finck static BYTE data88[] = {' ','<','h','e','a','d','>'};
592c2c66affSColin Finck static BYTE data89[] = {'\t','\r','<','h','e','a','d','>'};
593c2c66affSColin Finck static BYTE data90[] = {'<','H','e','A','d',' '};
594c2c66affSColin Finck static BYTE data91[] = {'<','?','x','m','l',' ',0};
595c2c66affSColin Finck static BYTE data92[] = {'a','b','c','<','?','x','m','l',' ',' '};
596c2c66affSColin Finck static BYTE data93[] = {'<','?','x','m','l',' ',' ','<','h','t','m','l','>'};
597c2c66affSColin Finck static BYTE data94[] = {'<','h','t','m','l','>','<','?','x','m','l',' ',' '};
598c2c66affSColin Finck static BYTE data95[] = {'{','\\','r','t','f','<','?','x','m','l',' ',' '};
599c2c66affSColin Finck static BYTE data96[] = {'<','?','x','m','l',' '};
600c2c66affSColin Finck static BYTE data97[] = "<body";
601c2c66affSColin Finck static BYTE data98[] = "blah<BoDyblahblah";
602c2c66affSColin Finck 
603c2c66affSColin Finck static const struct {
604c2c66affSColin Finck     BYTE *data;
605c2c66affSColin Finck     DWORD size;
606c2c66affSColin Finck     const char *mime;
607c2c66affSColin Finck     const char *mime_pjpeg;
608c2c66affSColin Finck     const char *broken_mime;
609c2c66affSColin Finck     const char *url;
610c2c66affSColin Finck     const char *proposed_mime;
611c2c66affSColin Finck } mime_tests2[] = {
612c2c66affSColin Finck     {data1, sizeof(data1), "text/plain"},
613c2c66affSColin Finck     {data2, sizeof(data2), "application/octet-stream", "image/pjpeg"},
614c2c66affSColin Finck     {data3, sizeof(data3), "application/octet-stream", "image/pjpeg"},
615c2c66affSColin Finck     {data4, sizeof(data4), "application/octet-stream", "image/pjpeg"},
616c2c66affSColin Finck     {data5, sizeof(data5), "text/plain"},
617c2c66affSColin Finck     {data6, sizeof(data6), "text/plain"},
618c2c66affSColin Finck     {data7, sizeof(data7), "text/html", "text/plain"},
619c2c66affSColin Finck     {data8, sizeof(data8), "text/html", "text/plain"},
620c2c66affSColin Finck     {data9, sizeof(data9), "text/html", "image/pjpeg"},
621c2c66affSColin Finck     {data10, sizeof(data10), "text/html", "text/plain"},
622c2c66affSColin Finck     {data11, sizeof(data11), "text/html", "text/plain"},
623c2c66affSColin Finck     {data12, sizeof(data12), "text/html", "text/plain"},
624c2c66affSColin Finck     {data13, sizeof(data13), "text/plain"},
625c2c66affSColin Finck     {data14, sizeof(data14), "text/plain"},
626c2c66affSColin Finck     {data15, sizeof(data15), "text/plain"},
627c2c66affSColin Finck     {data16, sizeof(data16), "image/pjpeg"},
628c2c66affSColin Finck     {data17, sizeof(data17), "application/octet-stream", "image/pjpeg"},
629c2c66affSColin Finck     {data18, sizeof(data18), "text/html", "image/pjpeg"},
630c2c66affSColin Finck     {data19, sizeof(data19), "image/gif"},
631c2c66affSColin Finck     {data20, sizeof(data20), "image/gif"},
632c2c66affSColin Finck     {data21, sizeof(data21), "text/plain"},
633c2c66affSColin Finck     {data22, sizeof(data22), "image/gif"},
634c2c66affSColin Finck     {data23, sizeof(data23), "text/plain"},
635c2c66affSColin Finck     {data24, sizeof(data24), "image/gif"},
636c2c66affSColin Finck     {data25, sizeof(data25), "image/gif"},
637c2c66affSColin Finck     {data26, sizeof(data26), "text/html", "image/gif"},
638c2c66affSColin Finck     {data27, sizeof(data27), "text/plain"},
639c2c66affSColin Finck     {data28, sizeof(data28), "image/bmp"},
640c2c66affSColin Finck     {data29, sizeof(data29), "image/bmp"},
641c2c66affSColin Finck     {data30, sizeof(data30), "application/octet-stream", "image/pjpeg"},
642c2c66affSColin Finck     {data31, sizeof(data31), "text/html", "image/bmp"},
643c2c66affSColin Finck     {data32, sizeof(data32), "application/octet-stream", "image/pjpeg"},
644c2c66affSColin Finck     {data33, sizeof(data33), "application/octet-stream", "image/pjpeg"},
645c2c66affSColin Finck     {data34, sizeof(data34), "image/x-png"},
646c2c66affSColin Finck     {data35, sizeof(data35), "image/x-png"},
647c2c66affSColin Finck     {data36, sizeof(data36), "application/octet-stream", "image/pjpeg"},
648c2c66affSColin Finck     {data37, sizeof(data37), "text/html", "image/x-png"},
649c2c66affSColin Finck     {data38, sizeof(data38), "application/octet-stream", "image/pjpeg"},
650c2c66affSColin Finck     {data39, sizeof(data39), "image/tiff"},
651c2c66affSColin Finck     {data40, sizeof(data40), "text/html", "image/tiff"},
652c2c66affSColin Finck     {data41, sizeof(data41), "text/plain", NULL, "image/tiff"},
653c2c66affSColin Finck     {data42, sizeof(data42), "text/plain"},
654c2c66affSColin Finck     {data43, sizeof(data43), "application/octet-stream", "image/pjpeg"},
655c2c66affSColin Finck     {data44, sizeof(data44), "video/avi"},
656c2c66affSColin Finck     {data45, sizeof(data45), "text/plain"},
657c2c66affSColin Finck     {data46, sizeof(data46), "text/plain"},
658c2c66affSColin Finck     {data47, sizeof(data47), "text/plain"},
659c2c66affSColin Finck     {data48, sizeof(data48), "text/html", "video/avi"},
660c2c66affSColin Finck     {data49, sizeof(data49), "video/avi"},
661c2c66affSColin Finck     {data50, sizeof(data50), "video/mpeg"},
662c2c66affSColin Finck     {data51, sizeof(data51), "video/mpeg"},
663c2c66affSColin Finck     {data52, sizeof(data52), "application/octet-stream", "image/pjpeg"},
664c2c66affSColin Finck     {data53, sizeof(data53), "application/octet-stream", "image/pjpeg", "image/x-icon"},
665c2c66affSColin Finck     {data54, sizeof(data54), "text/html", "video/mpeg"},
666c2c66affSColin Finck     {data55, sizeof(data55), "application/x-gzip-compressed"},
667c2c66affSColin Finck     {data56, sizeof(data56), "text/plain"},
668c2c66affSColin Finck     {data57, sizeof(data57), "text/html", "application/x-gzip-compressed"},
669c2c66affSColin Finck     {data58, sizeof(data58), "application/octet-stream", "image/pjpeg"},
670c2c66affSColin Finck     {data59, sizeof(data59), "application/x-zip-compressed"},
671c2c66affSColin Finck     {data60, sizeof(data60), "text/plain"},
672c2c66affSColin Finck     {data61, sizeof(data61), "text/html", "application/x-zip-compressed"},
673c2c66affSColin Finck     {data62, sizeof(data62), "application/java"},
674c2c66affSColin Finck     {data63, sizeof(data63), "text/plain"},
675c2c66affSColin Finck     {data64, sizeof(data64), "text/html", "application/java"},
676c2c66affSColin Finck     {data65, sizeof(data65), "application/pdf"},
677c2c66affSColin Finck     {data66, sizeof(data66), "text/plain"},
678c2c66affSColin Finck     {data67, sizeof(data67), "text/html", "application/pdf"},
679c2c66affSColin Finck     {data68, sizeof(data68), "application/x-msdownload"},
680c2c66affSColin Finck     {data69, sizeof(data69), "text/plain"},
681c2c66affSColin Finck     {data70, sizeof(data70), "text/html", "application/x-msdownload"},
682c2c66affSColin Finck     {data71, sizeof(data71), "text/richtext"},
683c2c66affSColin Finck     {data72, sizeof(data72), "text/plain"},
684c2c66affSColin Finck     {data73, sizeof(data73), "text/plain"},
685c2c66affSColin Finck     {data74, sizeof(data74), "text/html", "text/richtext"},
686c2c66affSColin Finck     {data75, sizeof(data75), "audio/wav"},
687c2c66affSColin Finck     {data76, sizeof(data76), "text/plain"},
688c2c66affSColin Finck     {data77, sizeof(data77), "text/plain"},
689c2c66affSColin Finck     {data78, sizeof(data78), "text/html", "text/plain"},
690c2c66affSColin Finck     {data79, sizeof(data79), "application/postscript"},
691c2c66affSColin Finck     {data80, sizeof(data80), "text/plain"},
692c2c66affSColin Finck     {data81, sizeof(data81), "text/html", "application/postscript"},
693c2c66affSColin Finck     {data82, sizeof(data82), "audio/basic"},
694c2c66affSColin Finck     {data83, sizeof(data83), "text/plain"},
695c2c66affSColin Finck     {data84, sizeof(data84), "text/html", "audio/basic"},
696c2c66affSColin Finck     {data85, sizeof(data85), "text/plain"},
697c2c66affSColin Finck     {data86, sizeof(data86), "image/tiff", NULL, "text/plain"},
698c2c66affSColin Finck     {data87, sizeof(data87), "text/plain"},
699c2c66affSColin Finck     {data88, sizeof(data88), "text/html", "text/plain"},
700c2c66affSColin Finck     {data89, sizeof(data89), "text/html", "text/plain"},
701c2c66affSColin Finck     {data90, sizeof(data90), "text/html", "text/plain"},
702c2c66affSColin Finck     {data91, sizeof(data91), "text/xml", "text/plain"},
703c2c66affSColin Finck     {data92, sizeof(data92), "text/xml", "text/plain"},
704c2c66affSColin Finck     {data93, sizeof(data93), "text/xml", "text/plain"},
705c2c66affSColin Finck     {data94, sizeof(data94), "text/html", "text/plain"},
706c2c66affSColin Finck     {data95, sizeof(data95), "text/xml", "text/richtext"},
707c2c66affSColin Finck     {data96, sizeof(data96), "text/plain"},
708c2c66affSColin Finck     {data97, sizeof(data97), "text/html", "text/plain"},
709c2c66affSColin Finck     {data98, sizeof(data98), "text/html", "text/plain"},
710c2c66affSColin Finck     {data1, sizeof(data1), "text/plain", NULL, NULL, "res://mshtml.dll/blank.htm"},
711c2c66affSColin Finck     {NULL, 0, "text/html", NULL, NULL, "res://mshtml.dll/blank.htm"},
712c2c66affSColin Finck     {data1, sizeof(data1), "text/plain", NULL, NULL, "res://mshtml.dll/blank.htm", "application/octet-stream"},
713c2c66affSColin Finck     {data1, sizeof(data1), "text/plain", NULL, NULL, "file:some%20file%2ejpg", "application/octet-stream"},
714c2c66affSColin Finck     {NULL, sizeof(data1), "text/html", NULL, NULL, "res://mshtml.dll/blank.htm"},
715c2c66affSColin Finck     {data1, sizeof(data1), "text/css", NULL, NULL, "http://www.winehq.org/test.css"},
716c2c66affSColin Finck     {data2, sizeof(data2), "text/css", NULL, NULL, "http://www.winehq.org/test.css"},
717c2c66affSColin Finck     {data10, sizeof(data10), "text/html", NULL, NULL, "http://www.winehq.org/test.css"},
718c2c66affSColin Finck     {data1, sizeof(data1), "text/css", NULL, NULL, "http://www.winehq.org/test.css", "text/plain"},
719c2c66affSColin Finck     {data1, sizeof(data1), "text/css", NULL, NULL, "http://www.winehq.org/test.css", "application/octet-stream"},
720c2c66affSColin Finck     {data1, sizeof(data1), "text/test", NULL, NULL, "http://www.winehq.org/test.css", "text/test"}
721c2c66affSColin Finck };
722c2c66affSColin Finck 
test_FindMimeFromData(void)723c2c66affSColin Finck static void test_FindMimeFromData(void)
724c2c66affSColin Finck {
725c2c66affSColin Finck     WCHAR *mime, *proposed_mime, *url;
726c2c66affSColin Finck     HRESULT hres;
727c2c66affSColin Finck     BYTE b;
728c2c66affSColin Finck     int i;
729c2c66affSColin Finck 
730c2c66affSColin Finck     static const WCHAR app_octet_streamW[] =
731c2c66affSColin Finck         {'a','p','p','l','i','c','a','t','i','o','n','/','o','c','t','e','t','-','s','t','r','e','a','m',0};
732c2c66affSColin Finck     static const WCHAR image_pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0};
733c2c66affSColin Finck     static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
734c2c66affSColin Finck     static const WCHAR text_plainW[] = {'t','e','x','t','/','p','l','a','i','n',0};
735c2c66affSColin Finck 
73611d1bab6SAmine Khaldi     for(i = 0; i < ARRAY_SIZE(mime_tests); i++) {
737c2c66affSColin Finck         mime = (LPWSTR)0xf0f0f0f0;
738c2c66affSColin Finck         url = a2w(mime_tests[i].url);
739c2c66affSColin Finck         hres = pFindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0);
740c2c66affSColin Finck         if(mime_tests[i].mime) {
741c2c66affSColin Finck             ok(hres == S_OK || broken(mime_tests[i].broken_failure), "[%d] FindMimeFromData failed: %08x\n", i, hres);
742c2c66affSColin Finck             if(hres == S_OK) {
743c2c66affSColin Finck                 ok(!strcmp_wa(mime, mime_tests[i].mime)
744c2c66affSColin Finck                    || broken(mime_tests[i].broken_mime && !strcmp_wa(mime, mime_tests[i].broken_mime)),
745c2c66affSColin Finck                    "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
746c2c66affSColin Finck                 CoTaskMemFree(mime);
747c2c66affSColin Finck             }
748c2c66affSColin Finck         }else {
749c2c66affSColin Finck             ok(hres == E_FAIL || hres == mime_tests[i].hres,
750c2c66affSColin Finck                "[%d] FindMimeFromData failed: %08x, expected %08x\n",
751c2c66affSColin Finck                i, hres, mime_tests[i].hres);
752c2c66affSColin Finck             ok(mime == (LPWSTR)0xf0f0f0f0, "[%d] mime != 0xf0f0f0f0\n", i);
753c2c66affSColin Finck         }
754c2c66affSColin Finck 
755c2c66affSColin Finck         mime = (LPWSTR)0xf0f0f0f0;
756c2c66affSColin Finck         hres = pFindMimeFromData(NULL, url, NULL, 0, text_plainW, 0, &mime, 0);
757c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
758c2c66affSColin Finck         ok(!strcmp_wa(mime, "text/plain"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
759c2c66affSColin Finck         CoTaskMemFree(mime);
760c2c66affSColin Finck 
761c2c66affSColin Finck         mime = (LPWSTR)0xf0f0f0f0;
762c2c66affSColin Finck         hres = pFindMimeFromData(NULL, url, NULL, 0, app_octet_streamW, 0, &mime, 0);
763c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
764c2c66affSColin Finck         ok(!strcmp_wa(mime, "application/octet-stream"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
765c2c66affSColin Finck         CoTaskMemFree(mime);
766c2c66affSColin Finck         heap_free(url);
767c2c66affSColin Finck     }
768c2c66affSColin Finck 
76911d1bab6SAmine Khaldi     for(i = 0; i < ARRAY_SIZE(mime_tests2); i++) {
770c2c66affSColin Finck         url = a2w(mime_tests2[i].url);
771c2c66affSColin Finck         proposed_mime = a2w(mime_tests2[i].proposed_mime);
772c2c66affSColin Finck         hres = pFindMimeFromData(NULL, url, mime_tests2[i].data, mime_tests2[i].size,
773c2c66affSColin Finck                 proposed_mime, 0, &mime, 0);
774c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
775c2c66affSColin Finck         b = !strcmp_wa(mime, mime_tests2[i].mime);
776c2c66affSColin Finck         ok(b || broken(mime_tests2[i].broken_mime && !strcmp_wa(mime, mime_tests2[i].broken_mime)),
777c2c66affSColin Finck             "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
778c2c66affSColin Finck         heap_free(proposed_mime);
779c2c66affSColin Finck         heap_free(url);
780c2c66affSColin Finck         CoTaskMemFree(mime);
781c2c66affSColin Finck         if(!b || url || proposed_mime)
782c2c66affSColin Finck             continue;
783c2c66affSColin Finck 
784c2c66affSColin Finck         hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
785c2c66affSColin Finck                 app_octet_streamW, 0, &mime, 0);
786c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
787c2c66affSColin Finck         ok(!strcmp_wa(mime, mime_tests2[i].mime) || broken(mime_tests2[i].broken_mime
788c2c66affSColin Finck                         && !strcmp_wa(mime, mime_tests2[i].broken_mime)),
789c2c66affSColin Finck                     "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
790c2c66affSColin Finck         CoTaskMemFree(mime);
791c2c66affSColin Finck 
792c2c66affSColin Finck         hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
793c2c66affSColin Finck                 text_plainW, 0, &mime, 0);
794c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
795c2c66affSColin Finck         ok(!strcmp_wa(mime, mime_tests2[i].mime) || broken(mime_tests2[i].broken_mime
796c2c66affSColin Finck                     && !strcmp_wa(mime, mime_tests2[i].broken_mime)),
797c2c66affSColin Finck                 "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
798c2c66affSColin Finck         CoTaskMemFree(mime);
799c2c66affSColin Finck 
800c2c66affSColin Finck         hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
801c2c66affSColin Finck                 text_htmlW, 0, &mime, 0);
802c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
803c2c66affSColin Finck         if(!strcmp("application/octet-stream", mime_tests2[i].mime)
804c2c66affSColin Finck            || !strcmp("text/plain", mime_tests2[i].mime) || i==92)
805c2c66affSColin Finck             ok(!strcmp_wa(mime, "text/html"), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
806c2c66affSColin Finck         else
807c2c66affSColin Finck             ok(!strcmp_wa(mime, mime_tests2[i].mime), "[%d] wrong mime: %s\n", i, wine_dbgstr_w(mime));
808c2c66affSColin Finck         CoTaskMemFree(mime);
809c2c66affSColin Finck 
810c2c66affSColin Finck         hres = pFindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
811c2c66affSColin Finck                 image_pjpegW, 0, &mime, 0);
812c2c66affSColin Finck         ok(hres == S_OK, "[%d] FindMimeFromData failed: %08x\n", i, hres);
813c2c66affSColin Finck         ok(!strcmp_wa(mime, mime_tests2[i].mime_pjpeg ? mime_tests2[i].mime_pjpeg : mime_tests2[i].mime)
814c2c66affSColin Finck            || broken(!strcmp_wa(mime, mime_tests2[i].mime)),
815c2c66affSColin Finck            "[%d] wrong mime, got %s\n", i, wine_dbgstr_w(mime));
816c2c66affSColin Finck         CoTaskMemFree(mime);
817c2c66affSColin Finck     }
818c2c66affSColin Finck 
819c2c66affSColin Finck     hres = pFindMimeFromData(NULL, NULL, NULL, 0, NULL, 0, &mime, 0);
820c2c66affSColin Finck     ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
821c2c66affSColin Finck 
822c2c66affSColin Finck     hres = pFindMimeFromData(NULL, NULL, NULL, 0, text_plainW, 0, &mime, 0);
823c2c66affSColin Finck     ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
824c2c66affSColin Finck 
825c2c66affSColin Finck     hres = pFindMimeFromData(NULL, NULL, data1, 0, NULL, 0, &mime, 0);
826c2c66affSColin Finck     ok(hres == E_FAIL, "FindMimeFromData failed: %08x, expected E_FAIL\n", hres);
827c2c66affSColin Finck 
828c2c66affSColin Finck     hres = pFindMimeFromData(NULL, url1, data1, 0, NULL, 0, &mime, 0);
829c2c66affSColin Finck     ok(hres == E_FAIL, "FindMimeFromData failed: %08x, expected E_FAIL\n", hres);
830c2c66affSColin Finck 
831c2c66affSColin Finck     hres = pFindMimeFromData(NULL, NULL, data1, 0, text_plainW, 0, &mime, 0);
832c2c66affSColin Finck     ok(hres == S_OK, "FindMimeFromData failed: %08x\n", hres);
833c2c66affSColin Finck     ok(!strcmp_wa(mime, "text/plain"), "wrong mime: %s\n", wine_dbgstr_w(mime));
834c2c66affSColin Finck     CoTaskMemFree(mime);
835c2c66affSColin Finck 
836c2c66affSColin Finck     hres = pFindMimeFromData(NULL, NULL, data1, 0, text_plainW, 0, NULL, 0);
837c2c66affSColin Finck     ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08x, expected E_INVALIDARG\n", hres);
838c2c66affSColin Finck }
839c2c66affSColin Finck 
register_protocols(void)840c2c66affSColin Finck static void register_protocols(void)
841c2c66affSColin Finck {
842c2c66affSColin Finck     IInternetSession *session;
843c2c66affSColin Finck     IClassFactory *factory;
844c2c66affSColin Finck     HRESULT hres;
845c2c66affSColin Finck 
846c2c66affSColin Finck     static const WCHAR wszAbout[] = {'a','b','o','u','t',0};
847c2c66affSColin Finck 
848c2c66affSColin Finck     hres = pCoInternetGetSession(0, &session, 0);
849c2c66affSColin Finck     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
850c2c66affSColin Finck     if(FAILED(hres))
851c2c66affSColin Finck         return;
852c2c66affSColin Finck 
853c2c66affSColin Finck     hres = CoGetClassObject(&CLSID_AboutProtocol, CLSCTX_INPROC_SERVER, NULL,
854c2c66affSColin Finck             &IID_IClassFactory, (void**)&factory);
855c2c66affSColin Finck     ok(hres == S_OK, "Could not get AboutProtocol factory: %08x\n", hres);
856c2c66affSColin Finck     if(FAILED(hres))
857c2c66affSColin Finck         return;
858c2c66affSColin Finck 
859c2c66affSColin Finck     IInternetSession_RegisterNameSpace(session, factory, &CLSID_AboutProtocol,
860c2c66affSColin Finck                                        wszAbout, 0, NULL, 0);
861c2c66affSColin Finck     IClassFactory_Release(factory);
862c2c66affSColin Finck 
863c2c66affSColin Finck     IInternetSession_Release(session);
864c2c66affSColin Finck }
865c2c66affSColin Finck 
InternetProtocolInfo_QueryInterface(IInternetProtocolInfo * iface,REFIID riid,void ** ppv)866c2c66affSColin Finck static HRESULT WINAPI InternetProtocolInfo_QueryInterface(IInternetProtocolInfo *iface,
867c2c66affSColin Finck                                                           REFIID riid, void **ppv)
868c2c66affSColin Finck {
869c2c66affSColin Finck     ok(0, "unexpected call\n");
870c2c66affSColin Finck     return E_NOINTERFACE;
871c2c66affSColin Finck }
872c2c66affSColin Finck 
InternetProtocolInfo_AddRef(IInternetProtocolInfo * iface)873c2c66affSColin Finck static ULONG WINAPI InternetProtocolInfo_AddRef(IInternetProtocolInfo *iface)
874c2c66affSColin Finck {
875c2c66affSColin Finck     return 2;
876c2c66affSColin Finck }
877c2c66affSColin Finck 
InternetProtocolInfo_Release(IInternetProtocolInfo * iface)878c2c66affSColin Finck static ULONG WINAPI InternetProtocolInfo_Release(IInternetProtocolInfo *iface)
879c2c66affSColin Finck {
880c2c66affSColin Finck     return 1;
881c2c66affSColin Finck }
882c2c66affSColin Finck 
InternetProtocolInfo_ParseUrl(IInternetProtocolInfo * iface,LPCWSTR pwzUrl,PARSEACTION ParseAction,DWORD dwParseFlags,LPWSTR pwzResult,DWORD cchResult,DWORD * pcchResult,DWORD dwReserved)883c2c66affSColin Finck static HRESULT WINAPI InternetProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
884c2c66affSColin Finck         PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
885c2c66affSColin Finck         DWORD *pcchResult, DWORD dwReserved)
886c2c66affSColin Finck {
887*98e4a3ecSAmine Khaldi     switch(ParseAction) {
888*98e4a3ecSAmine Khaldi     case PARSE_SECURITY_URL:
889c2c66affSColin Finck         CHECK_EXPECT2(ParseUrl);
890c2c66affSColin Finck         if(pcchResult)
89111d1bab6SAmine Khaldi             *pcchResult = ARRAY_SIZE(url1);
892c2c66affSColin Finck 
89311d1bab6SAmine Khaldi         if(cchResult < ARRAY_SIZE(url1))
894c2c66affSColin Finck             return S_FALSE;
895c2c66affSColin Finck 
896c2c66affSColin Finck         memcpy(pwzResult, url1, sizeof(url1));
897c2c66affSColin Finck         return S_OK;
898*98e4a3ecSAmine Khaldi     case PARSE_ENCODE:
899*98e4a3ecSAmine Khaldi         CHECK_EXPECT2(ParseUrl_ENCODE);
900*98e4a3ecSAmine Khaldi         break;
901*98e4a3ecSAmine Khaldi 
902*98e4a3ecSAmine Khaldi     case PARSE_UNESCAPE:
903*98e4a3ecSAmine Khaldi         CHECK_EXPECT2(ParseUrl_UNESCAPE);
904*98e4a3ecSAmine Khaldi         break;
905*98e4a3ecSAmine Khaldi 
906*98e4a3ecSAmine Khaldi     default:
907*98e4a3ecSAmine Khaldi         CHECK_EXPECT2(ParseUrl);
908*98e4a3ecSAmine Khaldi         break;
909c2c66affSColin Finck     }
910c2c66affSColin Finck 
911c2c66affSColin Finck     return E_NOTIMPL;
912c2c66affSColin Finck }
913c2c66affSColin Finck 
InternetProtocolInfo_CombineUrl(IInternetProtocolInfo * iface,LPCWSTR pwzBaseUrl,LPCWSTR pwzRelativeUrl,DWORD dwCombineFlags,LPWSTR pwzResult,DWORD cchResult,DWORD * pcchResult,DWORD dwReserved)914c2c66affSColin Finck static HRESULT WINAPI InternetProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
915c2c66affSColin Finck         LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
916c2c66affSColin Finck         LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
917c2c66affSColin Finck {
918c2c66affSColin Finck     ok(0, "unexpected call\n");
919c2c66affSColin Finck     return E_NOTIMPL;
920c2c66affSColin Finck }
921c2c66affSColin Finck 
InternetProtocolInfo_CompareUrl(IInternetProtocolInfo * iface,LPCWSTR pwzUrl1,LPCWSTR pwzUrl2,DWORD dwCompareFlags)922c2c66affSColin Finck static HRESULT WINAPI InternetProtocolInfo_CompareUrl(IInternetProtocolInfo *iface,
923c2c66affSColin Finck         LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
924c2c66affSColin Finck {
925c2c66affSColin Finck     ok(0, "unexpected call\n");
926c2c66affSColin Finck     return E_NOTIMPL;
927c2c66affSColin Finck }
928c2c66affSColin Finck 
InternetProtocolInfo_QueryInfo(IInternetProtocolInfo * iface,LPCWSTR pwzUrl,QUERYOPTION OueryOption,DWORD dwQueryFlags,LPVOID pBuffer,DWORD cbBuffer,DWORD * pcbBuf,DWORD dwReserved)929c2c66affSColin Finck static HRESULT WINAPI InternetProtocolInfo_QueryInfo(IInternetProtocolInfo *iface,
930c2c66affSColin Finck         LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer,
931c2c66affSColin Finck         DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved)
932c2c66affSColin Finck {
933c2c66affSColin Finck     ok(0, "unexpected call\n");
934c2c66affSColin Finck     return E_NOTIMPL;
935c2c66affSColin Finck }
936c2c66affSColin Finck 
937c2c66affSColin Finck static const IInternetProtocolInfoVtbl InternetProtocolInfoVtbl = {
938c2c66affSColin Finck     InternetProtocolInfo_QueryInterface,
939c2c66affSColin Finck     InternetProtocolInfo_AddRef,
940c2c66affSColin Finck     InternetProtocolInfo_Release,
941c2c66affSColin Finck     InternetProtocolInfo_ParseUrl,
942c2c66affSColin Finck     InternetProtocolInfo_CombineUrl,
943c2c66affSColin Finck     InternetProtocolInfo_CompareUrl,
944c2c66affSColin Finck     InternetProtocolInfo_QueryInfo
945c2c66affSColin Finck };
946c2c66affSColin Finck 
947c2c66affSColin Finck static IInternetProtocolInfo protocol_info = { &InternetProtocolInfoVtbl };
948c2c66affSColin Finck 
949c2c66affSColin Finck static HRESULT qiret;
950c2c66affSColin Finck static IClassFactory *expect_cf;
951c2c66affSColin Finck 
ClassFactory_QueryInterface(IClassFactory * iface,REFIID riid,void ** ppv)952c2c66affSColin Finck static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
953c2c66affSColin Finck {
954c2c66affSColin Finck     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
955c2c66affSColin Finck         CHECK_EXPECT2(QI_IInternetProtocolInfo);
956c2c66affSColin Finck         ok(iface == expect_cf, "unexpected iface\n");
957c2c66affSColin Finck         *ppv = &protocol_info;
958c2c66affSColin Finck         return qiret;
959c2c66affSColin Finck     }
960c2c66affSColin Finck 
961c2c66affSColin Finck     ok(0, "unexpected call\n");
962c2c66affSColin Finck     return E_NOINTERFACE;
963c2c66affSColin Finck }
964c2c66affSColin Finck 
ClassFactory_AddRef(IClassFactory * iface)965c2c66affSColin Finck static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
966c2c66affSColin Finck {
967c2c66affSColin Finck     return 2;
968c2c66affSColin Finck }
969c2c66affSColin Finck 
ClassFactory_Release(IClassFactory * iface)970c2c66affSColin Finck static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
971c2c66affSColin Finck {
972c2c66affSColin Finck     return 1;
973c2c66affSColin Finck }
974c2c66affSColin Finck 
ClassFactory_CreateInstance(IClassFactory * iface,IUnknown * pOuter,REFIID riid,void ** ppv)975c2c66affSColin Finck static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
976c2c66affSColin Finck                                         REFIID riid, void **ppv)
977c2c66affSColin Finck {
978c2c66affSColin Finck     ok(0, "unexpected call\n");
979c2c66affSColin Finck     return E_NOTIMPL;
980c2c66affSColin Finck }
981c2c66affSColin Finck 
ProtocolCF_CreateInstance(IClassFactory * iface,IUnknown * pOuter,REFIID riid,void ** ppv)982c2c66affSColin Finck static HRESULT WINAPI ProtocolCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
983c2c66affSColin Finck                                         REFIID riid, void **ppv)
984c2c66affSColin Finck {
985c2c66affSColin Finck     CHECK_EXPECT(CreateInstance);
986c2c66affSColin Finck 
987c2c66affSColin Finck     ok(iface == expect_cf, "unexpected iface\n");
988c2c66affSColin Finck     ok(pOuter == NULL, "pOuter = %p\n", pOuter);
989c2c66affSColin Finck     ok(IsEqualGUID(&IID_IInternetProtocolInfo, riid), "unexpected riid\n");
990c2c66affSColin Finck     ok(ppv != NULL, "ppv == NULL\n");
991c2c66affSColin Finck 
992c2c66affSColin Finck     *ppv = &protocol_info;
993c2c66affSColin Finck     return S_OK;
994c2c66affSColin Finck }
995c2c66affSColin Finck 
ClassFactory_LockServer(IClassFactory * iface,BOOL dolock)996c2c66affSColin Finck static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
997c2c66affSColin Finck {
998c2c66affSColin Finck     ok(0, "unexpected call\n");
999c2c66affSColin Finck     return S_OK;
1000c2c66affSColin Finck }
1001c2c66affSColin Finck 
1002c2c66affSColin Finck static const IClassFactoryVtbl ClassFactoryVtbl = {
1003c2c66affSColin Finck     ClassFactory_QueryInterface,
1004c2c66affSColin Finck     ClassFactory_AddRef,
1005c2c66affSColin Finck     ClassFactory_Release,
1006c2c66affSColin Finck     ClassFactory_CreateInstance,
1007c2c66affSColin Finck     ClassFactory_LockServer
1008c2c66affSColin Finck };
1009c2c66affSColin Finck 
1010c2c66affSColin Finck static const IClassFactoryVtbl ProtocolCFVtbl = {
1011c2c66affSColin Finck     ClassFactory_QueryInterface,
1012c2c66affSColin Finck     ClassFactory_AddRef,
1013c2c66affSColin Finck     ClassFactory_Release,
1014c2c66affSColin Finck     ProtocolCF_CreateInstance,
1015c2c66affSColin Finck     ClassFactory_LockServer
1016c2c66affSColin Finck };
1017c2c66affSColin Finck 
1018c2c66affSColin Finck static IClassFactory test_protocol_cf = { &ProtocolCFVtbl };
1019c2c66affSColin Finck static IClassFactory test_protocol_cf2 = { &ProtocolCFVtbl };
1020c2c66affSColin Finck static IClassFactory test_cf = { &ClassFactoryVtbl };
1021c2c66affSColin Finck 
test_NameSpace(void)1022c2c66affSColin Finck static void test_NameSpace(void)
1023c2c66affSColin Finck {
1024c2c66affSColin Finck     IInternetSession *session;
1025c2c66affSColin Finck     WCHAR buf[200];
1026c2c66affSColin Finck     LPWSTR sec_url;
1027c2c66affSColin Finck     DWORD size;
1028c2c66affSColin Finck     HRESULT hres;
1029c2c66affSColin Finck 
1030c2c66affSColin Finck     static const WCHAR wszTest[] = {'t','e','s','t',0};
1031c2c66affSColin Finck 
1032c2c66affSColin Finck     hres = pCoInternetGetSession(0, &session, 0);
1033c2c66affSColin Finck     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
1034c2c66affSColin Finck     if(FAILED(hres))
1035c2c66affSColin Finck         return;
1036c2c66affSColin Finck 
1037c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, NULL, &IID_NULL,
1038c2c66affSColin Finck                                               wszTest, 0, NULL, 0);
1039c2c66affSColin Finck     ok(hres == E_INVALIDARG, "RegisterNameSpace failed: %08x\n", hres);
1040c2c66affSColin Finck 
1041c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1042c2c66affSColin Finck                                               NULL, 0, NULL, 0);
1043c2c66affSColin Finck     ok(hres == E_INVALIDARG, "RegisterNameSpace failed: %08x\n", hres);
1044c2c66affSColin Finck 
1045c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1046c2c66affSColin Finck                                               wszTest, 0, NULL, 0);
1047c2c66affSColin Finck     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1048c2c66affSColin Finck 
1049c2c66affSColin Finck     qiret = E_NOINTERFACE;
1050c2c66affSColin Finck     expect_cf = &test_protocol_cf;
1051c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1052c2c66affSColin Finck     SET_EXPECT(CreateInstance);
1053*98e4a3ecSAmine Khaldi     SET_EXPECT(ParseUrl_ENCODE);
1054c2c66affSColin Finck 
105511d1bab6SAmine Khaldi     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1056c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1057c2c66affSColin Finck 
1058c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1059c2c66affSColin Finck     CHECK_CALLED(CreateInstance);
1060*98e4a3ecSAmine Khaldi     CHECK_CALLED(ParseUrl_ENCODE);
1061c2c66affSColin Finck 
1062c2c66affSColin Finck     qiret = S_OK;
1063c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1064*98e4a3ecSAmine Khaldi     SET_EXPECT(ParseUrl_ENCODE);
1065c2c66affSColin Finck 
106611d1bab6SAmine Khaldi     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1067c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1068c2c66affSColin Finck 
1069c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1070*98e4a3ecSAmine Khaldi     CHECK_CALLED(ParseUrl_ENCODE);
1071*98e4a3ecSAmine Khaldi 
1072*98e4a3ecSAmine Khaldi     qiret = S_OK;
1073*98e4a3ecSAmine Khaldi     SET_EXPECT(QI_IInternetProtocolInfo);
1074*98e4a3ecSAmine Khaldi     SET_EXPECT(ParseUrl_UNESCAPE);
1075*98e4a3ecSAmine Khaldi 
1076*98e4a3ecSAmine Khaldi     hres = pCoInternetParseUrl(url8, PARSE_UNESCAPE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1077*98e4a3ecSAmine Khaldi     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1078*98e4a3ecSAmine Khaldi 
1079*98e4a3ecSAmine Khaldi     CHECK_CALLED(QI_IInternetProtocolInfo);
1080*98e4a3ecSAmine Khaldi     CHECK_CALLED(ParseUrl_UNESCAPE);
1081c2c66affSColin Finck 
1082c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1083c2c66affSColin Finck     SET_EXPECT(ParseUrl);
1084c2c66affSColin Finck 
108511d1bab6SAmine Khaldi     hres = pCoInternetParseUrl(url8, PARSE_SECURITY_URL, 0, buf, ARRAY_SIZE(buf), &size, 0);
1086c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
108711d1bab6SAmine Khaldi     ok(size == ARRAY_SIZE(url1), "Size = %d\n", size);
108811d1bab6SAmine Khaldi     if(size == ARRAY_SIZE(url1))
1089c2c66affSColin Finck         ok(!memcmp(buf, url1, sizeof(url1)), "Encoded url = %s\n", wine_dbgstr_w(buf));
1090c2c66affSColin Finck 
1091c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1092c2c66affSColin Finck     CHECK_CALLED(ParseUrl);
1093c2c66affSColin Finck 
1094c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1095c2c66affSColin Finck     SET_EXPECT(ParseUrl);
1096c2c66affSColin Finck 
1097c2c66affSColin Finck     if (pCoInternetGetSecurityUrl) {
1098c2c66affSColin Finck         hres = pCoInternetGetSecurityUrl(url8, &sec_url, PSU_SECURITY_URL_ONLY, 0);
1099c2c66affSColin Finck         ok(hres == S_OK, "CoInternetGetSecurityUrl failed: %08x\n", hres);
1100c2c66affSColin Finck         if(hres == S_OK) {
110111d1bab6SAmine Khaldi             ok(lstrlenW(sec_url) > ARRAY_SIZE(wszFile) &&
1102c2c66affSColin Finck                     !memcmp(sec_url, wszFile, sizeof(wszFile)-sizeof(WCHAR)),
1103c2c66affSColin Finck                     "Encoded url = %s\n", wine_dbgstr_w(sec_url));
1104c2c66affSColin Finck             CoTaskMemFree(sec_url);
1105c2c66affSColin Finck         }
1106c2c66affSColin Finck 
1107c2c66affSColin Finck         CHECK_CALLED(QI_IInternetProtocolInfo);
1108c2c66affSColin Finck         CHECK_CALLED(ParseUrl);
1109c2c66affSColin Finck     }
1110c2c66affSColin Finck 
1111c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1112c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1113c2c66affSColin Finck 
111411d1bab6SAmine Khaldi     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1115c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1116c2c66affSColin Finck 
1117c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf2, &IID_NULL,
1118c2c66affSColin Finck                                               wszTest, 0, NULL, 0);
1119c2c66affSColin Finck     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1120c2c66affSColin Finck 
1121c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1122c2c66affSColin Finck                                               wszTest, 0, NULL, 0);
1123c2c66affSColin Finck     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1124c2c66affSColin Finck 
1125c2c66affSColin Finck     hres = IInternetSession_RegisterNameSpace(session, &test_protocol_cf, &IID_NULL,
1126c2c66affSColin Finck                                               wszTest, 0, NULL, 0);
1127c2c66affSColin Finck     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
1128c2c66affSColin Finck 
1129c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1130*98e4a3ecSAmine Khaldi     SET_EXPECT(ParseUrl_ENCODE);
1131c2c66affSColin Finck 
113211d1bab6SAmine Khaldi     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1133c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1134c2c66affSColin Finck 
1135c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1136*98e4a3ecSAmine Khaldi     CHECK_CALLED(ParseUrl_ENCODE);
1137c2c66affSColin Finck 
1138c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1139c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1140c2c66affSColin Finck 
1141c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1142*98e4a3ecSAmine Khaldi     SET_EXPECT(ParseUrl_ENCODE);
1143c2c66affSColin Finck 
114411d1bab6SAmine Khaldi     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1145c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1146c2c66affSColin Finck 
1147c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1148*98e4a3ecSAmine Khaldi     CHECK_CALLED(ParseUrl_ENCODE);
1149c2c66affSColin Finck 
1150c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1151c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1152c2c66affSColin Finck 
1153c2c66affSColin Finck     expect_cf = &test_protocol_cf2;
1154c2c66affSColin Finck     SET_EXPECT(QI_IInternetProtocolInfo);
1155*98e4a3ecSAmine Khaldi     SET_EXPECT(ParseUrl_ENCODE);
1156c2c66affSColin Finck 
115711d1bab6SAmine Khaldi     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1158c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1159c2c66affSColin Finck 
1160c2c66affSColin Finck     CHECK_CALLED(QI_IInternetProtocolInfo);
1161*98e4a3ecSAmine Khaldi     CHECK_CALLED(ParseUrl_ENCODE);
1162c2c66affSColin Finck 
1163c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1164c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1165c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, wszTest);
1166c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1167c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf, NULL);
1168c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UnregisterNameSpace failed: %08x\n", hres);
1169c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, NULL, wszTest);
1170c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UnregisterNameSpace failed: %08x\n", hres);
1171c2c66affSColin Finck 
1172c2c66affSColin Finck     hres = IInternetSession_UnregisterNameSpace(session, &test_protocol_cf2, wszTest);
1173c2c66affSColin Finck     ok(hres == S_OK, "UnregisterNameSpace failed: %08x\n", hres);
1174c2c66affSColin Finck 
117511d1bab6SAmine Khaldi     hres = pCoInternetParseUrl(url8, PARSE_ENCODE, 0, buf, ARRAY_SIZE(buf), &size, 0);
1176c2c66affSColin Finck     ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres);
1177c2c66affSColin Finck 
1178c2c66affSColin Finck     IInternetSession_Release(session);
1179c2c66affSColin Finck }
1180c2c66affSColin Finck 
test_MimeFilter(void)1181c2c66affSColin Finck static void test_MimeFilter(void)
1182c2c66affSColin Finck {
1183c2c66affSColin Finck     IInternetSession *session;
1184c2c66affSColin Finck     HRESULT hres;
1185c2c66affSColin Finck 
1186c2c66affSColin Finck     static const WCHAR mimeW[] = {'t','e','s','t','/','m','i','m','e',0};
1187c2c66affSColin Finck 
1188c2c66affSColin Finck     hres = pCoInternetGetSession(0, &session, 0);
1189c2c66affSColin Finck     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
1190c2c66affSColin Finck     if(FAILED(hres))
1191c2c66affSColin Finck         return;
1192c2c66affSColin Finck 
1193c2c66affSColin Finck     hres = IInternetSession_RegisterMimeFilter(session, &test_cf, &IID_NULL, mimeW);
1194c2c66affSColin Finck     ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres);
1195c2c66affSColin Finck 
1196c2c66affSColin Finck     hres = IInternetSession_UnregisterMimeFilter(session, &test_cf, mimeW);
1197c2c66affSColin Finck     ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1198c2c66affSColin Finck 
1199c2c66affSColin Finck     hres = IInternetSession_UnregisterMimeFilter(session, &test_cf, mimeW);
1200c2c66affSColin Finck     ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1201c2c66affSColin Finck 
1202c2c66affSColin Finck     hres = IInternetSession_UnregisterMimeFilter(session, (void*)0xdeadbeef, mimeW);
1203c2c66affSColin Finck     ok(hres == S_OK, "UnregisterMimeFilter failed: %08x\n", hres);
1204c2c66affSColin Finck 
1205c2c66affSColin Finck     IInternetSession_Release(session);
1206c2c66affSColin Finck }
1207c2c66affSColin Finck 
unk_Release(IUnknown * iface)1208c2c66affSColin Finck static ULONG WINAPI unk_Release(IUnknown *iface)
1209c2c66affSColin Finck {
1210c2c66affSColin Finck     CHECK_EXPECT(unk_Release);
1211c2c66affSColin Finck     return 0;
1212c2c66affSColin Finck }
1213c2c66affSColin Finck 
1214c2c66affSColin Finck static const IUnknownVtbl unk_vtbl = {
1215c2c66affSColin Finck     (void*)0xdeadbeef,
1216c2c66affSColin Finck     (void*)0xdeadbeef,
1217c2c66affSColin Finck     unk_Release
1218c2c66affSColin Finck };
1219c2c66affSColin Finck 
test_ReleaseBindInfo(void)1220c2c66affSColin Finck static void test_ReleaseBindInfo(void)
1221c2c66affSColin Finck {
1222c2c66affSColin Finck     BINDINFO bi;
1223c2c66affSColin Finck     IUnknown unk = { &unk_vtbl };
1224c2c66affSColin Finck 
1225c2c66affSColin Finck     pReleaseBindInfo(NULL); /* shouldn't crash */
1226c2c66affSColin Finck 
1227c2c66affSColin Finck     memset(&bi, 0, sizeof(bi));
1228c2c66affSColin Finck     bi.cbSize = sizeof(BINDINFO);
1229c2c66affSColin Finck     bi.pUnk = &unk;
1230c2c66affSColin Finck     SET_EXPECT(unk_Release);
1231c2c66affSColin Finck     pReleaseBindInfo(&bi);
1232c2c66affSColin Finck     ok(bi.cbSize == sizeof(BINDINFO), "bi.cbSize=%d\n", bi.cbSize);
1233c2c66affSColin Finck     ok(bi.pUnk == NULL, "bi.pUnk=%p, expected NULL\n", bi.pUnk);
1234c2c66affSColin Finck     CHECK_CALLED(unk_Release);
1235c2c66affSColin Finck 
1236c2c66affSColin Finck     memset(&bi, 0, sizeof(bi));
1237c2c66affSColin Finck     bi.cbSize = offsetof(BINDINFO, pUnk);
1238c2c66affSColin Finck     bi.pUnk = &unk;
1239c2c66affSColin Finck     pReleaseBindInfo(&bi);
1240c2c66affSColin Finck     ok(bi.cbSize == offsetof(BINDINFO, pUnk), "bi.cbSize=%d\n", bi.cbSize);
1241c2c66affSColin Finck     ok(bi.pUnk == &unk, "bi.pUnk=%p, expected %p\n", bi.pUnk, &unk);
1242c2c66affSColin Finck 
1243c2c66affSColin Finck     memset(&bi, 0, sizeof(bi));
1244c2c66affSColin Finck     bi.pUnk = &unk;
1245c2c66affSColin Finck     pReleaseBindInfo(&bi);
1246c2c66affSColin Finck     ok(!bi.cbSize, "bi.cbSize=%d, expected 0\n", bi.cbSize);
1247c2c66affSColin Finck     ok(bi.pUnk == &unk, "bi.pUnk=%p, expected %p\n", bi.pUnk, &unk);
1248c2c66affSColin Finck }
1249c2c66affSColin Finck 
test_CopyStgMedium(void)1250c2c66affSColin Finck static void test_CopyStgMedium(void)
1251c2c66affSColin Finck {
1252c2c66affSColin Finck     STGMEDIUM src, dst;
1253c2c66affSColin Finck     HGLOBAL empty, hg;
1254c2c66affSColin Finck     char *ptr1, *ptr2;
1255c2c66affSColin Finck     HRESULT hres;
1256c2c66affSColin Finck     int size;
1257c2c66affSColin Finck 
1258c2c66affSColin Finck     static WCHAR fileW[] = {'f','i','l','e',0};
1259c2c66affSColin Finck 
1260c2c66affSColin Finck     memset(&src, 0xf0, sizeof(src));
1261c2c66affSColin Finck     memset(&dst, 0xe0, sizeof(dst));
1262c2c66affSColin Finck     memset(&empty, 0xf0, sizeof(empty));
1263c2c66affSColin Finck     src.tymed = TYMED_NULL;
1264c2c66affSColin Finck     src.pUnkForRelease = NULL;
1265c2c66affSColin Finck     hres = pCopyStgMedium(&src, &dst);
1266c2c66affSColin Finck     ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1267c2c66affSColin Finck     ok(dst.tymed == TYMED_NULL, "tymed=%d\n", dst.tymed);
1268c2c66affSColin Finck     ok(dst.u.hGlobal == empty, "u=%p\n", dst.u.hGlobal);
1269c2c66affSColin Finck     ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1270c2c66affSColin Finck 
1271c2c66affSColin Finck     memset(&dst, 0xe0, sizeof(dst));
1272c2c66affSColin Finck     src.tymed = TYMED_ISTREAM;
1273c2c66affSColin Finck     src.u.pstm = NULL;
1274c2c66affSColin Finck     src.pUnkForRelease = NULL;
1275c2c66affSColin Finck     hres = pCopyStgMedium(&src, &dst);
1276c2c66affSColin Finck     ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1277c2c66affSColin Finck     ok(dst.tymed == TYMED_ISTREAM, "tymed=%d\n", dst.tymed);
1278c2c66affSColin Finck     ok(!dst.u.pstm, "pstm=%p\n", dst.u.pstm);
1279c2c66affSColin Finck     ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1280c2c66affSColin Finck 
1281c2c66affSColin Finck     memset(&dst, 0xe0, sizeof(dst));
1282c2c66affSColin Finck     src.tymed = TYMED_FILE;
1283c2c66affSColin Finck     src.u.lpszFileName = fileW;
1284c2c66affSColin Finck     src.pUnkForRelease = NULL;
1285c2c66affSColin Finck     hres = pCopyStgMedium(&src, &dst);
1286c2c66affSColin Finck     ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1287c2c66affSColin Finck     ok(dst.tymed == TYMED_FILE, "tymed=%d\n", dst.tymed);
1288c2c66affSColin Finck     ok(dst.u.lpszFileName && dst.u.lpszFileName != fileW, "lpszFileName=%p\n", dst.u.lpszFileName);
1289c2c66affSColin Finck     ok(!lstrcmpW(dst.u.lpszFileName, fileW), "wrong file name\n");
1290c2c66affSColin Finck     ok(!dst.pUnkForRelease, "pUnkForRelease=%p, expected NULL\n", dst.pUnkForRelease);
1291c2c66affSColin Finck     ReleaseStgMedium(&dst);
1292c2c66affSColin Finck 
1293c2c66affSColin Finck     /* TYMED_HGLOBAL */
1294c2c66affSColin Finck     hg = GlobalAlloc(GMEM_MOVEABLE, 10);
1295c2c66affSColin Finck     ptr1 = GlobalLock(hg);
1296c2c66affSColin Finck     memset(ptr1, 0xfa, 10);
1297c2c66affSColin Finck     memset(&dst, 0xe0, sizeof(dst));
1298c2c66affSColin Finck     src.tymed = TYMED_HGLOBAL;
1299c2c66affSColin Finck     src.u.hGlobal = hg;
1300c2c66affSColin Finck     hres = pCopyStgMedium(&src, &dst);
1301c2c66affSColin Finck     ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1302c2c66affSColin Finck     ok(dst.tymed == TYMED_HGLOBAL, "tymed=%d\n", dst.tymed);
1303c2c66affSColin Finck     ok(dst.u.hGlobal != hg, "got %p, %p\n", dst.u.hGlobal, hg);
1304c2c66affSColin Finck     size = GlobalSize(dst.u.hGlobal);
1305c2c66affSColin Finck     ok(size == 10, "got size %d\n", size);
1306c2c66affSColin Finck     /* compare contents */
1307c2c66affSColin Finck     ptr2 = GlobalLock(dst.u.hGlobal);
1308c2c66affSColin Finck     ok(!memcmp(ptr1, ptr2, 10), "got wrong data\n");
1309c2c66affSColin Finck     GlobalUnlock(ptr2);
1310c2c66affSColin Finck     GlobalUnlock(ptr1);
1311c2c66affSColin Finck     ok(GlobalFlags(dst.u.hGlobal) == 0, "got 0x%08x\n", GlobalFlags(dst.u.hGlobal));
1312c2c66affSColin Finck     GlobalFree(hg);
1313c2c66affSColin Finck     ReleaseStgMedium(&dst);
1314c2c66affSColin Finck 
1315c2c66affSColin Finck     memset(&dst, 0xe0, sizeof(dst));
1316c2c66affSColin Finck     src.tymed = TYMED_HGLOBAL;
1317c2c66affSColin Finck     src.u.hGlobal = NULL;
1318c2c66affSColin Finck     hres = pCopyStgMedium(&src, &dst);
1319c2c66affSColin Finck     ok(hres == S_OK, "CopyStgMedium failed: %08x\n", hres);
1320c2c66affSColin Finck     ok(dst.u.hGlobal == NULL, "got %p\n", dst.u.hGlobal);
1321c2c66affSColin Finck 
1322c2c66affSColin Finck     hres = pCopyStgMedium(&src, NULL);
1323c2c66affSColin Finck     ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
1324c2c66affSColin Finck     hres = pCopyStgMedium(NULL, &dst);
1325c2c66affSColin Finck     ok(hres == E_POINTER, "CopyStgMedium failed: %08x, expected E_POINTER\n", hres);
1326c2c66affSColin Finck }
1327c2c66affSColin Finck 
test_CopyBindInfo(void)1328c2c66affSColin Finck static void test_CopyBindInfo(void)
1329c2c66affSColin Finck {
1330c2c66affSColin Finck     BINDINFO src[2], dest[2];
1331c2c66affSColin Finck     SECURITY_DESCRIPTOR sec_desc;
1332c2c66affSColin Finck     HRESULT hres;
1333c2c66affSColin Finck     int i;
1334c2c66affSColin Finck 
1335c2c66affSColin Finck     hres = pCopyBindInfo(NULL, NULL);
1336c2c66affSColin Finck     ok(hres == E_POINTER, "CopyBindInfo returned %08x, expected E_POINTER\n", hres);
1337c2c66affSColin Finck 
1338c2c66affSColin Finck     memset(src, 0, sizeof(BINDINFO[2]));
1339c2c66affSColin Finck     memset(dest, 0xde, sizeof(BINDINFO[2]));
1340c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1341c2c66affSColin Finck     ok(hres == E_INVALIDARG, "CopyBindInfo returned: %08x, expected E_INVALIDARG\n", hres);
1342c2c66affSColin Finck 
1343c2c66affSColin Finck     memset(src, 0, sizeof(BINDINFO[2]));
1344c2c66affSColin Finck     memset(dest, 0xde, sizeof(BINDINFO[2]));
1345c2c66affSColin Finck     src[0].cbSize = sizeof(BINDINFO);
1346c2c66affSColin Finck     dest[0].cbSize = 0;
1347c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1348c2c66affSColin Finck     ok(hres == E_INVALIDARG, "CopyBindInfo returned: %08x, expected E_INVALIDARG\n", hres);
1349c2c66affSColin Finck 
1350c2c66affSColin Finck     memset(src, 0, sizeof(BINDINFO[2]));
1351c2c66affSColin Finck     memset(dest, 0xde, sizeof(BINDINFO[2]));
1352c2c66affSColin Finck     src[0].cbSize = 1;
1353c2c66affSColin Finck     dest[0].cbSize = sizeof(BINDINFO)+sizeof(DWORD);
1354c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1355c2c66affSColin Finck     ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1356c2c66affSColin Finck     ok(dest[0].cbSize == sizeof(BINDINFO)+sizeof(DWORD), "incorrect cbSize: %d\n", dest[0].cbSize);
1357c2c66affSColin Finck     for(i=1; i<dest[0].cbSize/sizeof(int); i++)
1358c2c66affSColin Finck         ok(((int*)dest)[i] == 0, "unset values should be set to 0, got %d on %d\n", ((int*)dest)[i], i);
1359c2c66affSColin Finck 
1360c2c66affSColin Finck     memset(src, 0, sizeof(BINDINFO[2]));
1361c2c66affSColin Finck     memset(dest, 0xde, sizeof(BINDINFO[2]));
1362c2c66affSColin Finck     src[0].cbSize = sizeof(BINDINFO)+2*sizeof(DWORD);
1363c2c66affSColin Finck     dest[0].cbSize = sizeof(BINDINFO)+sizeof(DWORD);
1364c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1365c2c66affSColin Finck     ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1366c2c66affSColin Finck     ok(dest[1].cbSize == src[1].cbSize, "additional data should be copied\n");
1367c2c66affSColin Finck     ok(dest[1].szExtraInfo != src[1].szExtraInfo,
1368c2c66affSColin Finck             "data not fitting in destination buffer should not be copied\n");
1369c2c66affSColin Finck 
1370c2c66affSColin Finck     memset(src, 0xf0, sizeof(BINDINFO[2]));
1371c2c66affSColin Finck     memset(dest, 0xde, sizeof(BINDINFO[2]));
1372c2c66affSColin Finck     src[0].cbSize = sizeof(BINDINFO);
1373c2c66affSColin Finck     src[0].szExtraInfo = CoTaskMemAlloc(sizeof(WCHAR));
1374c2c66affSColin Finck     src[0].szExtraInfo[0] = 0;
1375c2c66affSColin Finck     src[0].szCustomVerb = NULL;
1376c2c66affSColin Finck     src[0].pUnk = NULL;
1377c2c66affSColin Finck     src[0].stgmedData.tymed = TYMED_NULL;
1378c2c66affSColin Finck     src[0].stgmedData.pUnkForRelease = NULL;
1379c2c66affSColin Finck     dest[0].cbSize = sizeof(BINDINFO);
1380c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1381c2c66affSColin Finck     ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1382c2c66affSColin Finck 
1383c2c66affSColin Finck     ok(dest[0].cbSize == sizeof(BINDINFO), "incorrect cbSize: %d\n", dest[0].cbSize);
1384c2c66affSColin Finck     ok(dest[0].szExtraInfo && !dest[0].szExtraInfo[0] && dest[0].szExtraInfo!=src[0].szExtraInfo,
1385c2c66affSColin Finck             "incorrect szExtraInfo: (%p!=%p) %d\n", dest[0].szExtraInfo,
1386c2c66affSColin Finck             src[0].szExtraInfo, dest[0].szExtraInfo[0]);
1387c2c66affSColin Finck     ok(!memcmp(&dest[0].stgmedData, &src[0].stgmedData, sizeof(STGMEDIUM)),
1388c2c66affSColin Finck             "incorrect stgmedData value\n");
1389c2c66affSColin Finck     ok(src[0].grfBindInfoF == dest[0].grfBindInfoF, "grfBindInfoF = %x, expected %x\n",
1390c2c66affSColin Finck             dest[0].grfBindInfoF, src[0].grfBindInfoF);
1391c2c66affSColin Finck     ok(src[0].dwBindVerb == dest[0].dwBindVerb, "dwBindVerb = %x, expected %x\n",
1392c2c66affSColin Finck             dest[0].dwBindVerb, src[0].dwBindVerb);
1393c2c66affSColin Finck     ok(!dest[0].szCustomVerb, "szCustmoVerb != NULL\n");
1394c2c66affSColin Finck     ok(src[0].cbstgmedData == dest[0].cbstgmedData, "cbstgmedData = %x, expected %x\n",
1395c2c66affSColin Finck             dest[0].cbstgmedData, src[0].cbstgmedData);
1396c2c66affSColin Finck     ok(src[0].dwOptions == dest[0].dwOptions, "dwOptions = %x, expected %x\n",
1397c2c66affSColin Finck             dest[0].dwOptions, src[0].dwOptions);
1398c2c66affSColin Finck     ok(src[0].dwOptionsFlags == dest[0].dwOptionsFlags, "dwOptionsFlags = %x, expected %x\n",
1399c2c66affSColin Finck             dest[0].dwOptionsFlags, src[0].dwOptionsFlags);
1400c2c66affSColin Finck     ok(src[0].dwCodePage == dest[0].dwCodePage, "dwCodePage = %x, expected %x\n",
1401c2c66affSColin Finck             dest[0].dwCodePage, src[0].dwCodePage);
1402c2c66affSColin Finck     ok(!dest[0].securityAttributes.nLength,
1403c2c66affSColin Finck             "unexpected securityAttributes.nLength value: %d\n",
1404c2c66affSColin Finck             dest[0].securityAttributes.nLength);
1405c2c66affSColin Finck     ok(!dest[0].securityAttributes.lpSecurityDescriptor,
1406c2c66affSColin Finck             "unexpected securityAttributes.lpSecurityDescriptor value: %p\n",
1407c2c66affSColin Finck             dest[0].securityAttributes.lpSecurityDescriptor);
1408c2c66affSColin Finck     ok(!dest[0].securityAttributes.bInheritHandle,
1409c2c66affSColin Finck             "unexpected securityAttributes.bInheritHandle value: %d\n",
1410c2c66affSColin Finck             dest[0].securityAttributes.bInheritHandle);
1411c2c66affSColin Finck     ok(!memcmp(&dest[0].iid, &src[0].iid, sizeof(IID)),
1412c2c66affSColin Finck             "incorrect iid value\n");
1413c2c66affSColin Finck     ok(!dest[0].pUnk, "pUnk != NULL\n");
1414c2c66affSColin Finck     ok(src[0].dwReserved == dest[0].dwReserved, "dwReserved = %x, expected %x\n",
1415c2c66affSColin Finck             dest[0].dwReserved, src[0].dwReserved);
1416c2c66affSColin Finck 
1417c2c66affSColin Finck     CoTaskMemFree(src[0].szExtraInfo);
1418c2c66affSColin Finck     CoTaskMemFree(dest[0].szExtraInfo);
1419c2c66affSColin Finck 
1420c2c66affSColin Finck     src[0].szExtraInfo = NULL;
1421c2c66affSColin Finck     src[0].securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
1422c2c66affSColin Finck     ok(InitializeSecurityDescriptor(&sec_desc, SECURITY_DESCRIPTOR_REVISION),
1423c2c66affSColin Finck             "InitializeSecurityDescriptor failed\n");
1424c2c66affSColin Finck     src[0].securityAttributes.lpSecurityDescriptor = (void*)&sec_desc;
1425c2c66affSColin Finck     src[0].securityAttributes.bInheritHandle = TRUE;
1426c2c66affSColin Finck     hres = pCopyBindInfo(src, dest);
1427c2c66affSColin Finck     ok(hres == S_OK, "CopyBindInfo failed: %08x\n", hres);
1428c2c66affSColin Finck     ok(!dest[0].securityAttributes.nLength,
1429c2c66affSColin Finck             "unexpected securityAttributes.nLength value: %d\n",
1430c2c66affSColin Finck             dest[0].securityAttributes.nLength);
1431c2c66affSColin Finck     ok(!dest[0].securityAttributes.lpSecurityDescriptor,
1432c2c66affSColin Finck             "unexpected securityAttributes.lpSecurityDescriptor value: %p\n",
1433c2c66affSColin Finck             dest[0].securityAttributes.lpSecurityDescriptor);
1434c2c66affSColin Finck     ok(!dest[0].securityAttributes.bInheritHandle,
1435c2c66affSColin Finck             "unexpected securityAttributes.bInheritHandle value: %d\n",
1436c2c66affSColin Finck             dest[0].securityAttributes.bInheritHandle);
1437c2c66affSColin Finck }
1438c2c66affSColin Finck 
test_UrlMkGetSessionOption(void)1439c2c66affSColin Finck static void test_UrlMkGetSessionOption(void)
1440c2c66affSColin Finck {
1441c2c66affSColin Finck     DWORD encoding, size;
1442c2c66affSColin Finck     HRESULT hres;
1443c2c66affSColin Finck 
1444c2c66affSColin Finck     size = encoding = 0xdeadbeef;
1445c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1446c2c66affSColin Finck                                  sizeof(encoding), &size, 0);
1447c2c66affSColin Finck     ok(hres == S_OK, "UrlMkGetSessionOption failed: %08x\n", hres);
1448c2c66affSColin Finck     ok(encoding != 0xdeadbeef, "encoding not changed\n");
1449c2c66affSColin Finck     ok(size == sizeof(encoding), "size=%d\n", size);
1450c2c66affSColin Finck 
1451c2c66affSColin Finck     size = encoding = 0xdeadbeef;
1452c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1453c2c66affSColin Finck                                  sizeof(encoding)+1, &size, 0);
1454c2c66affSColin Finck     ok(hres == S_OK, "UrlMkGetSessionOption failed: %08x\n", hres);
1455c2c66affSColin Finck     ok(encoding != 0xdeadbeef, "encoding not changed\n");
1456c2c66affSColin Finck     ok(size == sizeof(encoding), "size=%d\n", size);
1457c2c66affSColin Finck 
1458c2c66affSColin Finck     size = encoding = 0xdeadbeef;
1459c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1460c2c66affSColin Finck                                  sizeof(encoding)-1, &size, 0);
1461c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1462c2c66affSColin Finck     ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1463c2c66affSColin Finck     ok(size == 0xdeadbeef, "size=%d\n", size);
1464c2c66affSColin Finck 
1465c2c66affSColin Finck     size = encoding = 0xdeadbeef;
1466c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, NULL,
1467c2c66affSColin Finck                                  sizeof(encoding)-1, &size, 0);
1468c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1469c2c66affSColin Finck     ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1470c2c66affSColin Finck     ok(size == 0xdeadbeef, "size=%d\n", size);
1471c2c66affSColin Finck 
1472c2c66affSColin Finck     encoding = 0xdeadbeef;
1473c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &encoding,
1474c2c66affSColin Finck                                  sizeof(encoding)-1, NULL, 0);
1475c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1476c2c66affSColin Finck     ok(encoding == 0xdeadbeef, "encoding = %08x, exepcted 0xdeadbeef\n", encoding);
1477c2c66affSColin Finck }
1478c2c66affSColin Finck 
test_user_agent(void)1479c2c66affSColin Finck static void test_user_agent(void)
1480c2c66affSColin Finck {
1481c2c66affSColin Finck     static const CHAR expected[] = "Mozilla/4.0 (compatible; MSIE ";
1482c2c66affSColin Finck     static char test_str[] = "test";
1483c2c66affSColin Finck     static char test2_str[] = "test\0test";
1484c2c66affSColin Finck     static CHAR str[3];
1485c2c66affSColin Finck     LPSTR str2 = NULL;
1486c2c66affSColin Finck     HRESULT hres;
1487c2c66affSColin Finck     DWORD size, saved;
1488c2c66affSColin Finck 
1489c2c66affSColin Finck     hres = pObtainUserAgentString(0, NULL, NULL);
1490c2c66affSColin Finck     ok(hres == E_INVALIDARG, "ObtainUserAgentString failed: %08x\n", hres);
1491c2c66affSColin Finck 
1492c2c66affSColin Finck     size = 100;
1493c2c66affSColin Finck     hres = pObtainUserAgentString(0, NULL, &size);
1494c2c66affSColin Finck     ok(hres == E_INVALIDARG, "ObtainUserAgentString failed: %08x\n", hres);
1495c2c66affSColin Finck     ok(size == 100, "size=%d, expected %d\n", size, 100);
1496c2c66affSColin Finck 
1497c2c66affSColin Finck     size = 0;
1498c2c66affSColin Finck     hres = pObtainUserAgentString(0, str, &size);
1499c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1500c2c66affSColin Finck     ok(size > 0, "size=%d, expected non-zero\n", size);
1501c2c66affSColin Finck 
1502c2c66affSColin Finck     size = 2;
1503c2c66affSColin Finck     str[0] = 'a';
1504c2c66affSColin Finck     hres = pObtainUserAgentString(0, str, &size);
1505c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1506c2c66affSColin Finck     ok(size > 0, "size=%d, expected non-zero\n", size);
1507c2c66affSColin Finck     ok(str[0] == 'a', "str[0]=%c, expected 'a'\n", str[0]);
1508c2c66affSColin Finck 
1509c2c66affSColin Finck     size = 0;
1510c2c66affSColin Finck     hres = pObtainUserAgentString(1, str, &size);
1511c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "ObtainUserAgentString failed: %08x\n", hres);
1512c2c66affSColin Finck     ok(size > 0, "size=%d, expected non-zero\n", size);
1513c2c66affSColin Finck 
1514c2c66affSColin Finck     str2 = HeapAlloc(GetProcessHeap(), 0, (size+20)*sizeof(CHAR));
1515c2c66affSColin Finck     saved = size;
1516c2c66affSColin Finck     hres = pObtainUserAgentString(0, str2, &size);
1517c2c66affSColin Finck     ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
1518c2c66affSColin Finck     ok(size == saved, "size=%d, expected %d\n", size, saved);
1519c2c66affSColin Finck     ok(strlen(expected) <= strlen(str2) &&
1520c2c66affSColin Finck        !memcmp(expected, str2, strlen(expected)*sizeof(CHAR)),
1521c2c66affSColin Finck        "user agent was \"%s\", expected to start with \"%s\"\n",
1522c2c66affSColin Finck        str2, expected);
1523c2c66affSColin Finck 
1524c2c66affSColin Finck     size = saved+10;
1525c2c66affSColin Finck     hres = pObtainUserAgentString(0, str2, &size);
1526c2c66affSColin Finck     ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
1527c2c66affSColin Finck     ok(size == saved, "size=%d, expected %d\n", size, saved);
1528c2c66affSColin Finck 
1529c2c66affSColin Finck     size = 0;
1530c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, NULL, 0, &size, 0);
1531c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1532c2c66affSColin Finck     ok(size, "size == 0\n");
1533c2c66affSColin Finck 
1534c2c66affSColin Finck     size = 0xdeadbeef;
1535c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, NULL, 1000, &size, 0);
1536c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1537c2c66affSColin Finck     ok(size, "size == 0\n");
1538c2c66affSColin Finck 
1539c2c66affSColin Finck     saved = size;
1540c2c66affSColin Finck     size = 0;
1541c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved+10, &size, 0);
1542c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1543c2c66affSColin Finck     ok(size == saved, "size = %d, expected %d\n", size, saved);
1544c2c66affSColin Finck     ok(sizeof(expected) <= strlen(str2) && !memcmp(expected, str2, sizeof(expected)-1),
1545c2c66affSColin Finck        "user agent was \"%s\", expected to start with \"%s\"\n",
1546c2c66affSColin Finck        str2, expected);
1547c2c66affSColin Finck 
1548c2c66affSColin Finck     size = 0;
1549c2c66affSColin Finck     str2[0] = 0;
1550c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1551c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1552c2c66affSColin Finck     ok(size == saved, "size = %d, expected %d\n", size, saved);
1553c2c66affSColin Finck     ok(sizeof(expected) <= strlen(str2) && !memcmp(expected, str2, sizeof(expected)-1),
1554c2c66affSColin Finck        "user agent was \"%s\", expected to start with \"%s\"\n",
1555c2c66affSColin Finck        str2, expected);
1556c2c66affSColin Finck 
1557c2c66affSColin Finck     size = saved;
1558c2c66affSColin Finck     str2[0] = 0;
1559c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved-1, &size, 0);
1560c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1561c2c66affSColin Finck     ok(size == saved, "size = %d, expected %d\n", size, saved);
1562c2c66affSColin Finck     ok(!str2[0], "buf changed\n");
1563c2c66affSColin Finck 
1564c2c66affSColin Finck     size = saved;
1565c2c66affSColin Finck     str2[0] = 0;
1566c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, NULL, 0);
1567c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkGetSessionOption failed: %08x\n", hres);
1568c2c66affSColin Finck     ok(!str2[0], "buf changed\n");
1569c2c66affSColin Finck 
1570c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, sizeof(test_str), 0);
1571c2c66affSColin Finck     ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1572c2c66affSColin Finck 
1573c2c66affSColin Finck     size = 0;
1574c2c66affSColin Finck     str2[0] = 0;
1575c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1576c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1577c2c66affSColin Finck     ok(size == sizeof(test_str) && !memcmp(str2, test_str, sizeof(test_str)), "wrong user agent\n");
1578c2c66affSColin Finck 
1579c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test2_str, sizeof(test2_str), 0);
1580c2c66affSColin Finck     ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1581c2c66affSColin Finck 
1582c2c66affSColin Finck     size = 0;
1583c2c66affSColin Finck     str2[0] = 0;
1584c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1585c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1586c2c66affSColin Finck     ok(size == sizeof(test_str) && !memcmp(str2, test_str, sizeof(test_str)), "wrong user agent\n");
1587c2c66affSColin Finck 
1588c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, 2, 0);
1589c2c66affSColin Finck     ok(hres == S_OK, "UrlMkSetSessionOption failed: %08x\n", hres);
1590c2c66affSColin Finck 
1591c2c66affSColin Finck     size = 0;
1592c2c66affSColin Finck     str2[0] = 0;
1593c2c66affSColin Finck     hres = pUrlMkGetSessionOption(URLMON_OPTION_USERAGENT, str2, saved, &size, 0);
1594c2c66affSColin Finck     ok(hres == E_OUTOFMEMORY, "UrlMkGetSessionOption failed: %08x\n", hres);
1595c2c66affSColin Finck     ok(size == 3 && !strcmp(str2, "te"), "wrong user agent\n");
1596c2c66affSColin Finck 
1597c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, test_str, 0, 0);
1598c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1599c2c66affSColin Finck 
1600c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, NULL, sizeof(test_str), 0);
1601c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1602c2c66affSColin Finck 
1603c2c66affSColin Finck     hres = UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, NULL, 0, 0);
1604c2c66affSColin Finck     ok(hres == E_INVALIDARG, "UrlMkSetSessionOption failed: %08x\n", hres);
1605c2c66affSColin Finck 
1606c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, str2);
1607c2c66affSColin Finck }
1608c2c66affSColin Finck 
test_MkParseDisplayNameEx(void)1609c2c66affSColin Finck static void test_MkParseDisplayNameEx(void)
1610c2c66affSColin Finck {
1611c2c66affSColin Finck     IMoniker *mon = NULL;
1612c2c66affSColin Finck     LPWSTR name;
1613c2c66affSColin Finck     DWORD issys;
1614c2c66affSColin Finck     ULONG eaten = 0;
1615c2c66affSColin Finck     IBindCtx *bctx;
1616c2c66affSColin Finck     HRESULT hres;
1617c2c66affSColin Finck 
1618c2c66affSColin Finck     static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':',
1619c2c66affSColin Finck             '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8',
1620c2c66affSColin Finck             '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
1621c2c66affSColin Finck 
1622c2c66affSColin Finck     const struct
1623c2c66affSColin Finck     {
1624c2c66affSColin Finck         LPBC *ppbc;
1625c2c66affSColin Finck         LPCWSTR szDisplayName;
1626c2c66affSColin Finck         ULONG *pchEaten;
1627c2c66affSColin Finck         LPMONIKER *ppmk;
1628c2c66affSColin Finck     } invalid_parameters[] =
1629c2c66affSColin Finck     {
1630c2c66affSColin Finck         {NULL,  NULL,     NULL,   NULL},
1631c2c66affSColin Finck         {NULL,  NULL,     NULL,   &mon},
1632c2c66affSColin Finck         {NULL,  NULL,     &eaten, NULL},
1633c2c66affSColin Finck         {NULL,  NULL,     &eaten, &mon},
1634c2c66affSColin Finck         {NULL,  wszEmpty, NULL,   NULL},
1635c2c66affSColin Finck         {NULL,  wszEmpty, NULL,   &mon},
1636c2c66affSColin Finck         {NULL,  wszEmpty, &eaten, NULL},
1637c2c66affSColin Finck         {NULL,  wszEmpty, &eaten, &mon},
1638c2c66affSColin Finck         {&bctx, NULL,     NULL,   NULL},
1639c2c66affSColin Finck         {&bctx, NULL,     NULL,   &mon},
1640c2c66affSColin Finck         {&bctx, NULL,     &eaten, NULL},
1641c2c66affSColin Finck         {&bctx, NULL,     &eaten, &mon},
1642c2c66affSColin Finck         {&bctx, wszEmpty, NULL,   NULL},
1643c2c66affSColin Finck         {&bctx, wszEmpty, NULL,   &mon},
1644c2c66affSColin Finck         {&bctx, wszEmpty, &eaten, NULL},
1645c2c66affSColin Finck         {&bctx, wszEmpty, &eaten, &mon},
1646c2c66affSColin Finck     };
1647c2c66affSColin Finck 
1648c2c66affSColin Finck     int i;
1649c2c66affSColin Finck 
1650c2c66affSColin Finck     CreateBindCtx(0, &bctx);
1651c2c66affSColin Finck 
165211d1bab6SAmine Khaldi     for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
1653c2c66affSColin Finck     {
1654c2c66affSColin Finck         eaten = 0xdeadbeef;
1655c2c66affSColin Finck         mon = (IMoniker *)0xdeadbeef;
1656c2c66affSColin Finck         hres = MkParseDisplayNameEx(invalid_parameters[i].ppbc ? *invalid_parameters[i].ppbc : NULL,
1657c2c66affSColin Finck                                     invalid_parameters[i].szDisplayName,
1658c2c66affSColin Finck                                     invalid_parameters[i].pchEaten,
1659c2c66affSColin Finck                                     invalid_parameters[i].ppmk);
1660c2c66affSColin Finck         ok(hres == E_INVALIDARG,
1661c2c66affSColin Finck             "[%d] Expected MkParseDisplayNameEx to return E_INVALIDARG, got %08x\n", i, hres);
1662c2c66affSColin Finck         ok(eaten == 0xdeadbeef, "[%d] Expected eaten to be 0xdeadbeef, got %u\n", i, eaten);
1663c2c66affSColin Finck         ok(mon == (IMoniker *)0xdeadbeef, "[%d] Expected mon to be 0xdeadbeef, got %p\n", i, mon);
1664c2c66affSColin Finck     }
1665c2c66affSColin Finck 
1666c2c66affSColin Finck     hres = MkParseDisplayNameEx(bctx, url9, &eaten, &mon);
1667c2c66affSColin Finck     ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
166811d1bab6SAmine Khaldi     ok(eaten == ARRAY_SIZE(url9)-1, "eaten=%d\n", eaten);
1669c2c66affSColin Finck     ok(mon != NULL, "mon == NULL\n");
1670c2c66affSColin Finck 
1671c2c66affSColin Finck     hres = IMoniker_GetDisplayName(mon, NULL, 0, &name);
1672c2c66affSColin Finck     ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
1673c2c66affSColin Finck     ok(!lstrcmpW(name, url9), "wrong display name %s\n", wine_dbgstr_w(name));
1674c2c66affSColin Finck     CoTaskMemFree(name);
1675c2c66affSColin Finck 
1676c2c66affSColin Finck     hres = IMoniker_IsSystemMoniker(mon, &issys);
1677c2c66affSColin Finck     ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
1678c2c66affSColin Finck     ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys);
1679c2c66affSColin Finck 
1680c2c66affSColin Finck     IMoniker_Release(mon);
1681c2c66affSColin Finck 
1682c2c66affSColin Finck     hres = MkParseDisplayNameEx(bctx, clsid_nameW, &eaten, &mon);
1683c2c66affSColin Finck     ok(hres == S_OK, "MkParseDisplayNameEx failed: %08x\n", hres);
168411d1bab6SAmine Khaldi     ok(eaten == ARRAY_SIZE(clsid_nameW)-1, "eaten=%d\n", eaten);
1685c2c66affSColin Finck     ok(mon != NULL, "mon == NULL\n");
1686c2c66affSColin Finck 
1687c2c66affSColin Finck     hres = IMoniker_IsSystemMoniker(mon, &issys);
1688c2c66affSColin Finck     ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
1689c2c66affSColin Finck     ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys);
1690c2c66affSColin Finck 
1691c2c66affSColin Finck     IMoniker_Release(mon);
1692c2c66affSColin Finck 
1693c2c66affSColin Finck     hres = MkParseDisplayNameEx(bctx, url8, &eaten, &mon);
1694c2c66affSColin Finck     ok(FAILED(hres), "MkParseDisplayNameEx succeeded: %08x\n", hres);
1695c2c66affSColin Finck 
1696c2c66affSColin Finck     IBindCtx_Release(bctx);
1697c2c66affSColin Finck }
1698c2c66affSColin Finck 
test_IsValidURL(void)1699c2c66affSColin Finck static void test_IsValidURL(void)
1700c2c66affSColin Finck {
1701c2c66affSColin Finck     HRESULT hr;
1702c2c66affSColin Finck     IBindCtx *bctx = NULL;
1703c2c66affSColin Finck 
1704c2c66affSColin Finck     hr = IsValidURL(NULL, 0, 0);
1705c2c66affSColin Finck     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
1706c2c66affSColin Finck 
1707c2c66affSColin Finck     hr = IsValidURL(NULL, wszHttpWineHQ, 0);
1708c2c66affSColin Finck     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1709c2c66affSColin Finck 
1710c2c66affSColin Finck     CreateBindCtx(0, &bctx);
1711c2c66affSColin Finck 
1712c2c66affSColin Finck     hr = IsValidURL(bctx, wszHttpWineHQ, 0);
1713c2c66affSColin Finck     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1714c2c66affSColin Finck 
1715c2c66affSColin Finck     IBindCtx_Release(bctx);
1716c2c66affSColin Finck }
1717c2c66affSColin Finck 
1718c2c66affSColin Finck static const struct {
1719c2c66affSColin Finck     INTERNETFEATURELIST feature;
1720c2c66affSColin Finck     DWORD               get_flags;
1721c2c66affSColin Finck     HRESULT             expected;
1722c2c66affSColin Finck     BOOL                todo;
1723c2c66affSColin Finck } default_feature_tests[] = {
1724c2c66affSColin Finck     {FEATURE_OBJECT_CACHING,GET_FEATURE_FROM_PROCESS,S_OK},
1725c2c66affSColin Finck     {FEATURE_ZONE_ELEVATION,GET_FEATURE_FROM_PROCESS,S_FALSE},
1726c2c66affSColin Finck     {FEATURE_MIME_HANDLING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1727c2c66affSColin Finck     {FEATURE_MIME_SNIFFING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1728c2c66affSColin Finck     {FEATURE_WINDOW_RESTRICTIONS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1729c2c66affSColin Finck     {FEATURE_WEBOC_POPUPMANAGEMENT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1730c2c66affSColin Finck     {FEATURE_BEHAVIORS,GET_FEATURE_FROM_PROCESS,S_OK},
1731c2c66affSColin Finck     {FEATURE_DISABLE_MK_PROTOCOL,GET_FEATURE_FROM_PROCESS,S_OK},
1732c2c66affSColin Finck     {FEATURE_LOCALMACHINE_LOCKDOWN,GET_FEATURE_FROM_PROCESS,S_FALSE},
1733c2c66affSColin Finck     {FEATURE_SECURITYBAND,GET_FEATURE_FROM_PROCESS,S_FALSE},
1734c2c66affSColin Finck     {FEATURE_RESTRICT_ACTIVEXINSTALL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1735c2c66affSColin Finck     {FEATURE_VALIDATE_NAVIGATE_URL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1736c2c66affSColin Finck     {FEATURE_RESTRICT_FILEDOWNLOAD,GET_FEATURE_FROM_PROCESS,S_FALSE},
1737c2c66affSColin Finck     {FEATURE_ADDON_MANAGEMENT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1738c2c66affSColin Finck     {FEATURE_PROTOCOL_LOCKDOWN,GET_FEATURE_FROM_PROCESS,S_FALSE},
1739c2c66affSColin Finck     {FEATURE_HTTP_USERNAME_PASSWORD_DISABLE,GET_FEATURE_FROM_PROCESS,S_FALSE},
1740c2c66affSColin Finck     {FEATURE_SAFE_BINDTOOBJECT,GET_FEATURE_FROM_PROCESS,S_FALSE},
1741c2c66affSColin Finck     {FEATURE_UNC_SAVEDFILECHECK,GET_FEATURE_FROM_PROCESS,S_FALSE},
1742c2c66affSColin Finck     {FEATURE_GET_URL_DOM_FILEPATH_UNENCODED,GET_FEATURE_FROM_PROCESS,S_OK},
1743c2c66affSColin Finck     {FEATURE_TABBED_BROWSING,GET_FEATURE_FROM_PROCESS,S_FALSE},
1744c2c66affSColin Finck     {FEATURE_SSLUX,GET_FEATURE_FROM_PROCESS,S_FALSE},
1745c2c66affSColin Finck     {FEATURE_DISABLE_NAVIGATION_SOUNDS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1746c2c66affSColin Finck     {FEATURE_DISABLE_LEGACY_COMPRESSION,GET_FEATURE_FROM_PROCESS,S_OK},
1747c2c66affSColin Finck     {FEATURE_FORCE_ADDR_AND_STATUS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1748c2c66affSColin Finck     {FEATURE_XMLHTTP,GET_FEATURE_FROM_PROCESS,S_OK},
1749c2c66affSColin Finck     {FEATURE_DISABLE_TELNET_PROTOCOL,GET_FEATURE_FROM_PROCESS,S_FALSE},
1750c2c66affSColin Finck     {FEATURE_FEEDS,GET_FEATURE_FROM_PROCESS,S_FALSE},
1751c2c66affSColin Finck     {FEATURE_BLOCK_INPUT_PROMPTS,GET_FEATURE_FROM_PROCESS,S_FALSE}
1752c2c66affSColin Finck };
1753c2c66affSColin Finck 
test_internet_feature_defaults(void)1754c2c66affSColin Finck static void test_internet_feature_defaults(void) {
1755c2c66affSColin Finck     HRESULT hres;
1756c2c66affSColin Finck     DWORD i;
1757c2c66affSColin Finck 
175811d1bab6SAmine Khaldi     for(i = 0; i < ARRAY_SIZE(default_feature_tests); ++i) {
1759c2c66affSColin Finck         hres = pCoInternetIsFeatureEnabled(default_feature_tests[i].feature, default_feature_tests[i].get_flags);
1760c2c66affSColin Finck         todo_wine_if (default_feature_tests[i].todo)
1761c2c66affSColin Finck             ok(hres == default_feature_tests[i].expected, "CoInternetIsFeatureEnabled returned %08x, expected %08x on test %d\n",
1762c2c66affSColin Finck                 hres, default_feature_tests[i].expected, i);
1763c2c66affSColin Finck     }
1764c2c66affSColin Finck }
1765c2c66affSColin Finck 
1766c2c66affSColin Finck /* With older versions of IE (IE 7 and earlier), urlmon caches
1767c2c66affSColin Finck  * the FeatureControl values from the registry when it's loaded
1768c2c66affSColin Finck  * into memory. Newer versions of IE conditionally cache the
1769c2c66affSColin Finck  * the FeatureControl registry values (i.e. When a call to
1770c2c66affSColin Finck  * CoInternetIsFeatureEnabled and a corresponding CoInternetSetFeatureEnabled
1771c2c66affSColin Finck  * call hasn't already been made for the specified Feature). Because of
1772c2c66affSColin Finck  * this we skip these tests on IE 7 and earlier.
1773c2c66affSColin Finck  */
1774c2c66affSColin Finck static const char* szFeatureControlKey = "Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl";
1775c2c66affSColin Finck 
test_internet_features_registry(void)1776c2c66affSColin Finck static void test_internet_features_registry(void) {
1777c2c66affSColin Finck     HRESULT hres;
1778c2c66affSColin Finck     DWORD res;
1779c2c66affSColin Finck     char module[MAX_PATH];
1780c2c66affSColin Finck     char *name;
1781c2c66affSColin Finck     HKEY feature_control;
1782c2c66affSColin Finck     HKEY feature;
1783c2c66affSColin Finck     DWORD value;
1784c2c66affSColin Finck     BOOL skip_zone;
1785c2c66affSColin Finck     BOOL delete_feature_key = TRUE;
1786c2c66affSColin Finck 
1787c2c66affSColin Finck     static const char* szFeatureBehaviorsKey = "FEATURE_BEHAVIORS";
1788c2c66affSColin Finck     static const char* szFeatureZoneElevationKey = "FEATURE_ZONE_ELEVATION";
1789c2c66affSColin Finck 
1790c2c66affSColin Finck     if(!pIEInstallScope) {
1791c2c66affSColin Finck         win_skip("Skipping internet feature registry tests, IE is too old...\n");
1792c2c66affSColin Finck         return;
1793c2c66affSColin Finck     }
1794c2c66affSColin Finck 
1795c2c66affSColin Finck     res = GetModuleFileNameA(NULL, module, sizeof(module));
1796c2c66affSColin Finck     ok(res, "GetModuleFileName failed: %d\n", GetLastError());
1797c2c66affSColin Finck 
1798c2c66affSColin Finck     name = strrchr(module, '\\')+1;
1799c2c66affSColin Finck 
1800c2c66affSColin Finck     /* Some Windows machines don't have a FeatureControl key in HKCU. */
1801c2c66affSColin Finck     res = RegOpenKeyA(HKEY_CURRENT_USER, szFeatureControlKey, &feature_control);
1802c2c66affSColin Finck     ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1803c2c66affSColin Finck 
1804c2c66affSColin Finck     res = RegOpenKeyA(feature_control, szFeatureBehaviorsKey, &feature);
1805c2c66affSColin Finck     if(res == ERROR_SUCCESS) {
1806c2c66affSColin Finck         /* FEATURE_BEHAVIORS already existed, so don't delete it when we're done. */
1807c2c66affSColin Finck         delete_feature_key = FALSE;
1808c2c66affSColin Finck     }else {
1809c2c66affSColin Finck         res = RegCreateKeyA(feature_control, szFeatureBehaviorsKey, &feature);
1810c2c66affSColin Finck         ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1811c2c66affSColin Finck     }
1812c2c66affSColin Finck 
1813c2c66affSColin Finck     value = 0;
1814c2c66affSColin Finck     res = RegSetValueExA(feature, name, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
1815c2c66affSColin Finck     ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
1816c2c66affSColin Finck 
1817c2c66affSColin Finck     hres = pCoInternetIsFeatureEnabled(FEATURE_BEHAVIORS, GET_FEATURE_FROM_PROCESS);
1818c2c66affSColin Finck     ok(hres == S_FALSE, "CoInternetIsFeatureEnabled returned %08x, expected S_FALSE\n", hres);
1819c2c66affSColin Finck 
1820c2c66affSColin Finck     if(delete_feature_key) {
1821c2c66affSColin Finck         RegCloseKey(feature);
1822c2c66affSColin Finck         RegDeleteKeyA(feature_control, szFeatureBehaviorsKey);
1823c2c66affSColin Finck     } else {
1824c2c66affSColin Finck         RegDeleteValueA(feature, name);
1825c2c66affSColin Finck         RegCloseKey(feature);
1826c2c66affSColin Finck     }
1827c2c66affSColin Finck 
1828c2c66affSColin Finck     /* IE's feature control cached the value it got from the registry earlier. */
1829c2c66affSColin Finck     hres = pCoInternetIsFeatureEnabled(FEATURE_BEHAVIORS, GET_FEATURE_FROM_PROCESS);
1830c2c66affSColin Finck     ok(hres == S_FALSE, "CoInternetIsFeatureEnabled returned %08x, expected S_FALSE\n", hres);
1831c2c66affSColin Finck 
1832c2c66affSColin Finck     /* Restore this feature back to its default value. */
1833c2c66affSColin Finck     hres = pCoInternetSetFeatureEnabled(FEATURE_BEHAVIORS, SET_FEATURE_ON_PROCESS, TRUE);
1834c2c66affSColin Finck     ok(hres == S_OK, "CoInternetSetFeatureEnabled failed: %08x\n", hres);
1835c2c66affSColin Finck 
1836c2c66affSColin Finck     RegCloseKey(feature_control);
1837c2c66affSColin Finck 
1838c2c66affSColin Finck     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, szFeatureControlKey, &feature_control);
1839c2c66affSColin Finck     ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
1840c2c66affSColin Finck 
1841c2c66affSColin Finck     res = RegOpenKeyA(feature_control, szFeatureZoneElevationKey, &feature);
1842c2c66affSColin Finck     ok(res == ERROR_SUCCESS, "RegOpenKey failed: %d\n", res);
1843c2c66affSColin Finck 
1844c2c66affSColin Finck     value = 1;
1845c2c66affSColin Finck     res = RegSetValueExA(feature, "*", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
1846c2c66affSColin Finck     if (res == ERROR_ACCESS_DENIED)
1847c2c66affSColin Finck     {
1848c2c66affSColin Finck         skip("Not allowed to modify zone elevation\n");
1849c2c66affSColin Finck         skip_zone = TRUE;
1850c2c66affSColin Finck     }
1851c2c66affSColin Finck     else
1852c2c66affSColin Finck     {
1853c2c66affSColin Finck         skip_zone = FALSE;
1854c2c66affSColin Finck         ok(res == ERROR_SUCCESS, "RegSetValueEx failed: %d\n", res);
1855c2c66affSColin Finck 
1856c2c66affSColin Finck         hres = pCoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, GET_FEATURE_FROM_PROCESS);
1857c2c66affSColin Finck         ok(hres == S_OK, "CoInternetIsFeatureEnabled returned %08x, expected S_OK\n", hres);
1858c2c66affSColin Finck     }
1859c2c66affSColin Finck     RegDeleteValueA(feature, "*");
1860c2c66affSColin Finck     RegCloseKey(feature);
1861c2c66affSColin Finck     RegCloseKey(feature_control);
1862c2c66affSColin Finck 
1863c2c66affSColin Finck     /* Value is still cached from last time. */
1864c2c66affSColin Finck     if (!skip_zone)
1865c2c66affSColin Finck     {
1866c2c66affSColin Finck         hres = pCoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, GET_FEATURE_FROM_PROCESS);
1867c2c66affSColin Finck         ok(hres == S_OK, "CoInternetIsFeatureEnabled returned %08x, expected S_OK\n", hres);
1868c2c66affSColin Finck 
1869c2c66affSColin Finck         hres = pCoInternetSetFeatureEnabled(FEATURE_ZONE_ELEVATION, SET_FEATURE_ON_PROCESS, FALSE);
1870c2c66affSColin Finck         ok(hres == S_OK, "CoInternetSetFeatureEnabled failed: %08x\n", hres);
1871c2c66affSColin Finck     }
1872c2c66affSColin Finck 
1873c2c66affSColin Finck     test_internet_feature_defaults();
1874c2c66affSColin Finck }
1875c2c66affSColin Finck 
test_CoInternetIsFeatureEnabled(void)1876c2c66affSColin Finck static void test_CoInternetIsFeatureEnabled(void) {
1877c2c66affSColin Finck     HRESULT hres;
1878c2c66affSColin Finck 
1879c2c66affSColin Finck     hres = pCoInternetIsFeatureEnabled(FEATURE_ENTRY_COUNT, GET_FEATURE_FROM_PROCESS);
1880c2c66affSColin Finck     ok(hres == E_FAIL, "CoInternetIsFeatureEnabled returned %08x, expected E_FAIL\n", hres);
1881c2c66affSColin Finck }
1882c2c66affSColin Finck 
1883c2c66affSColin Finck static const struct {
1884c2c66affSColin Finck     INTERNETFEATURELIST feature;
1885c2c66affSColin Finck     DWORD               set_flags;
1886c2c66affSColin Finck     BOOL                enable;
1887c2c66affSColin Finck     HRESULT             set_expected;
1888c2c66affSColin Finck     BOOL                set_todo;
1889c2c66affSColin Finck     DWORD               get_flags;
1890c2c66affSColin Finck     HRESULT             get_expected;
1891c2c66affSColin Finck     BOOL                get_todo;
1892c2c66affSColin Finck } internet_feature_tests[] = {
1893c2c66affSColin Finck     {FEATURE_OBJECT_CACHING,SET_FEATURE_ON_PROCESS,FALSE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_FALSE},
1894c2c66affSColin Finck     {FEATURE_WEBOC_POPUPMANAGEMENT,SET_FEATURE_ON_PROCESS,TRUE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_OK},
1895c2c66affSColin Finck     {FEATURE_LOCALMACHINE_LOCKDOWN,SET_FEATURE_ON_PROCESS,TRUE,S_OK,FALSE,GET_FEATURE_FROM_PROCESS,S_OK}
1896c2c66affSColin Finck };
1897c2c66affSColin Finck 
test_CoInternetSetFeatureEnabled(void)1898c2c66affSColin Finck static void test_CoInternetSetFeatureEnabled(void) {
1899c2c66affSColin Finck     HRESULT hres;
1900c2c66affSColin Finck     DWORD i;
1901c2c66affSColin Finck 
1902c2c66affSColin Finck     hres = pCoInternetSetFeatureEnabled(FEATURE_ENTRY_COUNT,SET_FEATURE_ON_PROCESS,TRUE);
1903c2c66affSColin Finck     ok(hres == E_FAIL, "CoInternetSetFeatureEnabled returned %08x, expected E_FAIL\n", hres);
1904c2c66affSColin Finck 
190511d1bab6SAmine Khaldi     for(i = 0; i < ARRAY_SIZE(internet_feature_tests); ++i) {
1906c2c66affSColin Finck         hres = pCoInternetSetFeatureEnabled(internet_feature_tests[i].feature, internet_feature_tests[i].set_flags,
1907c2c66affSColin Finck                                             internet_feature_tests[i].enable);
1908c2c66affSColin Finck         todo_wine_if (internet_feature_tests[i].set_todo)
1909c2c66affSColin Finck             ok(hres == internet_feature_tests[i].set_expected, "CoInternetSetFeatureEnabled returned %08x, expected %08x on test %d\n",
1910c2c66affSColin Finck                 hres, internet_feature_tests[i].set_expected, i);
1911c2c66affSColin Finck 
1912c2c66affSColin Finck         hres = pCoInternetIsFeatureEnabled(internet_feature_tests[i].feature, internet_feature_tests[i].set_flags);
1913c2c66affSColin Finck         todo_wine_if (internet_feature_tests[i].get_todo)
1914c2c66affSColin Finck             ok(hres == internet_feature_tests[i].get_expected, "CoInternetIsFeatureEnabled returned %08x, expected %08x on test %d\n",
1915c2c66affSColin Finck                 hres, internet_feature_tests[i].get_expected, i);
1916c2c66affSColin Finck 
1917c2c66affSColin Finck     }
1918c2c66affSColin Finck }
1919c2c66affSColin Finck 
test_internet_features(void)1920c2c66affSColin Finck static void test_internet_features(void) {
1921c2c66affSColin Finck     HKEY key;
1922c2c66affSColin Finck     DWORD res;
1923c2c66affSColin Finck 
1924c2c66affSColin Finck     if(!pCoInternetIsFeatureEnabled || !pCoInternetSetFeatureEnabled) {
1925c2c66affSColin Finck         win_skip("Skipping internet feature tests, IE is too old\n");
1926c2c66affSColin Finck         return;
1927c2c66affSColin Finck     }
1928c2c66affSColin Finck 
1929c2c66affSColin Finck     /* IE10 takes FeatureControl key into account only if it's available upon process start. */
1930c2c66affSColin Finck     res = RegOpenKeyA(HKEY_CURRENT_USER, szFeatureControlKey, &key);
1931c2c66affSColin Finck     if(res != ERROR_SUCCESS) {
1932c2c66affSColin Finck         PROCESS_INFORMATION pi;
1933c2c66affSColin Finck         STARTUPINFOA si = { 0 };
1934c2c66affSColin Finck         char cmdline[MAX_PATH];
1935c2c66affSColin Finck         char **argv;
1936c2c66affSColin Finck         BOOL ret;
1937c2c66affSColin Finck 
1938c2c66affSColin Finck         res = RegCreateKeyA(HKEY_CURRENT_USER, szFeatureControlKey, &key);
1939c2c66affSColin Finck         ok(res == ERROR_SUCCESS, "RegCreateKey failed: %d\n", res);
1940c2c66affSColin Finck 
1941c2c66affSColin Finck         trace("Running features tests in a separated process.\n");
1942c2c66affSColin Finck 
1943c2c66affSColin Finck         winetest_get_mainargs( &argv );
1944c2c66affSColin Finck         sprintf(cmdline, "\"%s\" %s internet_features", argv[0], argv[1]);
1945c2c66affSColin Finck         ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
1946c2c66affSColin Finck         ok(ret, "Could not create process: %u\n", GetLastError());
1947c2c66affSColin Finck         winetest_wait_child_process( pi.hProcess );
1948c2c66affSColin Finck         CloseHandle(pi.hThread);
1949c2c66affSColin Finck         CloseHandle(pi.hProcess);
1950c2c66affSColin Finck 
1951c2c66affSColin Finck         RegDeleteKeyA(HKEY_CURRENT_USER, szFeatureControlKey);
1952c2c66affSColin Finck         return;
1953c2c66affSColin Finck     }
1954c2c66affSColin Finck 
1955c2c66affSColin Finck     test_internet_features_registry();
1956c2c66affSColin Finck     test_CoInternetIsFeatureEnabled();
1957c2c66affSColin Finck     test_CoInternetSetFeatureEnabled();
1958c2c66affSColin Finck }
1959c2c66affSColin Finck 
1960eb91a739SAmine Khaldi static BINDINFO rem_bindinfo = { sizeof(rem_bindinfo) }, in_bindinfo;
1961eb91a739SAmine Khaldi static DWORD rem_bindf;
1962eb91a739SAmine Khaldi 
BindStatusCallback_QueryInterface(IBindStatusCallbackEx * iface,REFIID riid,void ** ppv)1963eb91a739SAmine Khaldi static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallbackEx *iface, REFIID riid, void **ppv)
1964eb91a739SAmine Khaldi {
1965eb91a739SAmine Khaldi     if(IsEqualGUID(&IID_IBindStatusCallbackEx, riid)
1966eb91a739SAmine Khaldi        || IsEqualGUID(&IID_IBindStatusCallback, riid)
1967eb91a739SAmine Khaldi        || IsEqualGUID(&IID_IUnknown, riid)) {
1968eb91a739SAmine Khaldi         *ppv = iface;
1969eb91a739SAmine Khaldi         return S_OK;
1970eb91a739SAmine Khaldi     }
1971eb91a739SAmine Khaldi 
1972eb91a739SAmine Khaldi     *ppv = NULL;
1973eb91a739SAmine Khaldi     return E_NOINTERFACE;
1974eb91a739SAmine Khaldi }
1975eb91a739SAmine Khaldi 
BindStatusCallback_AddRef(IBindStatusCallbackEx * iface)1976eb91a739SAmine Khaldi static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallbackEx *iface)
1977eb91a739SAmine Khaldi {
1978eb91a739SAmine Khaldi     return 2;
1979eb91a739SAmine Khaldi }
1980eb91a739SAmine Khaldi 
BindStatusCallback_Release(IBindStatusCallbackEx * iface)1981eb91a739SAmine Khaldi static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallbackEx *iface)
1982eb91a739SAmine Khaldi {
1983eb91a739SAmine Khaldi     return 1;
1984eb91a739SAmine Khaldi }
1985eb91a739SAmine Khaldi 
BindStatusCallback_OnStartBinding(IBindStatusCallbackEx * iface,DWORD dwReserved,IBinding * pib)1986eb91a739SAmine Khaldi static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallbackEx *iface,
1987eb91a739SAmine Khaldi         DWORD dwReserved, IBinding *pib)
1988eb91a739SAmine Khaldi {
1989eb91a739SAmine Khaldi     ok(0, "unexpected call\n");
1990eb91a739SAmine Khaldi     return S_OK;
1991eb91a739SAmine Khaldi }
1992eb91a739SAmine Khaldi 
BindStatusCallback_GetPriority(IBindStatusCallbackEx * iface,LONG * pnPriority)1993eb91a739SAmine Khaldi static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallbackEx *iface, LONG *pnPriority)
1994eb91a739SAmine Khaldi {
1995eb91a739SAmine Khaldi     ok(0, "unexpected call\n");
1996eb91a739SAmine Khaldi     return E_NOTIMPL;
1997eb91a739SAmine Khaldi }
1998eb91a739SAmine Khaldi 
BindStatusCallback_OnLowResource(IBindStatusCallbackEx * iface,DWORD reserved)1999eb91a739SAmine Khaldi static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallbackEx *iface, DWORD reserved)
2000eb91a739SAmine Khaldi {
2001eb91a739SAmine Khaldi     ok(0, "unexpected call\n");
2002eb91a739SAmine Khaldi     return E_NOTIMPL;
2003eb91a739SAmine Khaldi }
2004eb91a739SAmine Khaldi 
BindStatusCallback_OnProgress(IBindStatusCallbackEx * iface,ULONG ulProgress,ULONG ulProgressMax,ULONG ulStatusCode,LPCWSTR szStatusText)2005eb91a739SAmine Khaldi static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallbackEx *iface, ULONG ulProgress,
2006eb91a739SAmine Khaldi         ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
2007eb91a739SAmine Khaldi {
2008eb91a739SAmine Khaldi     ok(0, "unexpected call\n");
2009eb91a739SAmine Khaldi     return S_OK;
2010eb91a739SAmine Khaldi }
2011eb91a739SAmine Khaldi 
BindStatusCallback_OnStopBinding(IBindStatusCallbackEx * iface,HRESULT hresult,LPCWSTR szError)2012eb91a739SAmine Khaldi static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallbackEx *iface, HRESULT hresult, LPCWSTR szError)
2013eb91a739SAmine Khaldi {
2014eb91a739SAmine Khaldi     ok(0, "unexpected call\n");
2015eb91a739SAmine Khaldi     return S_OK;
2016eb91a739SAmine Khaldi }
2017eb91a739SAmine Khaldi 
BindStatusCallback_GetBindInfo(IBindStatusCallbackEx * iface,DWORD * grfBINDF,BINDINFO * pbindinfo)2018eb91a739SAmine Khaldi static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallbackEx *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
2019eb91a739SAmine Khaldi {
2020eb91a739SAmine Khaldi     in_bindinfo = *pbindinfo;
2021eb91a739SAmine Khaldi     *grfBINDF = rem_bindf;
2022eb91a739SAmine Khaldi     *pbindinfo = rem_bindinfo;
2023eb91a739SAmine Khaldi     return S_OK;
2024eb91a739SAmine Khaldi }
2025eb91a739SAmine Khaldi 
2026eb91a739SAmine Khaldi static STGMEDIUM in_stgmed, rem_stgmed;
2027eb91a739SAmine Khaldi 
BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx * iface,DWORD grfBSCF,DWORD dwSize,FORMATETC * pformatetc,STGMEDIUM * pstgmed)2028eb91a739SAmine Khaldi static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx *iface, DWORD grfBSCF,
2029eb91a739SAmine Khaldi         DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
2030eb91a739SAmine Khaldi {
2031eb91a739SAmine Khaldi     in_stgmed = *pstgmed;
2032eb91a739SAmine Khaldi     *pstgmed = rem_stgmed;
2033eb91a739SAmine Khaldi     return S_OK;
2034eb91a739SAmine Khaldi }
2035eb91a739SAmine Khaldi 
BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx * iface,REFIID riid,IUnknown * punk)2036eb91a739SAmine Khaldi static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx *iface, REFIID riid, IUnknown *punk)
2037eb91a739SAmine Khaldi {
2038eb91a739SAmine Khaldi     ok(0, "unexpected call\n");
2039eb91a739SAmine Khaldi     return S_OK;
2040eb91a739SAmine Khaldi }
2041eb91a739SAmine Khaldi 
BindStatusCallbackEx_GetBindInfoEx(IBindStatusCallbackEx * iface,DWORD * grfBINDF,BINDINFO * pbindinfo,DWORD * grfBINDF2,DWORD * pdwReserved)2042eb91a739SAmine Khaldi static HRESULT WINAPI BindStatusCallbackEx_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF,
2043eb91a739SAmine Khaldi         BINDINFO *pbindinfo, DWORD *grfBINDF2, DWORD *pdwReserved)
2044eb91a739SAmine Khaldi {
2045eb91a739SAmine Khaldi     in_bindinfo = *pbindinfo;
2046eb91a739SAmine Khaldi     *grfBINDF = rem_bindf;
2047eb91a739SAmine Khaldi     *pbindinfo = rem_bindinfo;
2048eb91a739SAmine Khaldi     *grfBINDF2 = 11;
2049eb91a739SAmine Khaldi     *pdwReserved = 12;
2050eb91a739SAmine Khaldi     return S_OK;
2051eb91a739SAmine Khaldi }
2052eb91a739SAmine Khaldi 
2053eb91a739SAmine Khaldi static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl = {
2054eb91a739SAmine Khaldi     BindStatusCallback_QueryInterface,
2055eb91a739SAmine Khaldi     BindStatusCallback_AddRef,
2056eb91a739SAmine Khaldi     BindStatusCallback_Release,
2057eb91a739SAmine Khaldi     BindStatusCallback_OnStartBinding,
2058eb91a739SAmine Khaldi     BindStatusCallback_GetPriority,
2059eb91a739SAmine Khaldi     BindStatusCallback_OnLowResource,
2060eb91a739SAmine Khaldi     BindStatusCallback_OnProgress,
2061eb91a739SAmine Khaldi     BindStatusCallback_OnStopBinding,
2062eb91a739SAmine Khaldi     BindStatusCallback_GetBindInfo,
2063eb91a739SAmine Khaldi     BindStatusCallback_OnDataAvailable,
2064eb91a739SAmine Khaldi     BindStatusCallback_OnObjectAvailable,
2065eb91a739SAmine Khaldi     BindStatusCallbackEx_GetBindInfoEx
2066eb91a739SAmine Khaldi };
2067eb91a739SAmine Khaldi 
2068eb91a739SAmine Khaldi static IBindStatusCallbackEx BindStatusCallback = { &BindStatusCallbackExVtbl };
2069eb91a739SAmine Khaldi 
2070eb91a739SAmine Khaldi typedef struct {
2071eb91a739SAmine Khaldi     IUnknown IUnknown_iface;
2072eb91a739SAmine Khaldi     LONG ref;
2073eb91a739SAmine Khaldi } RefUnk;
2074eb91a739SAmine Khaldi 
impl_from_IUnknown(IUnknown * iface)2075eb91a739SAmine Khaldi static inline RefUnk *impl_from_IUnknown(IUnknown *iface)
2076eb91a739SAmine Khaldi {
2077eb91a739SAmine Khaldi     return CONTAINING_RECORD(iface, RefUnk, IUnknown_iface);
2078eb91a739SAmine Khaldi }
2079eb91a739SAmine Khaldi 
RefUnk_QueryInterface(IUnknown * iface,REFIID riid,void ** ppv)2080eb91a739SAmine Khaldi static HRESULT WINAPI RefUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
2081eb91a739SAmine Khaldi {
2082eb91a739SAmine Khaldi     if(!IsEqualGUID(&IID_IUnknown, riid)) {
2083eb91a739SAmine Khaldi         *ppv = NULL;
2084eb91a739SAmine Khaldi         return E_NOINTERFACE;
2085eb91a739SAmine Khaldi     }
2086eb91a739SAmine Khaldi 
2087eb91a739SAmine Khaldi     IUnknown_AddRef(iface);
2088eb91a739SAmine Khaldi     *ppv = iface;
2089eb91a739SAmine Khaldi     return S_OK;
2090eb91a739SAmine Khaldi }
2091eb91a739SAmine Khaldi 
RefUnk_AddRef(IUnknown * iface)2092eb91a739SAmine Khaldi static ULONG WINAPI RefUnk_AddRef(IUnknown *iface)
2093eb91a739SAmine Khaldi {
2094eb91a739SAmine Khaldi     RefUnk *This = impl_from_IUnknown(iface);
2095eb91a739SAmine Khaldi     return InterlockedIncrement(&This->ref);
2096eb91a739SAmine Khaldi }
2097eb91a739SAmine Khaldi 
RefUnk_Release(IUnknown * iface)2098eb91a739SAmine Khaldi static ULONG WINAPI RefUnk_Release(IUnknown *iface)
2099eb91a739SAmine Khaldi {
2100eb91a739SAmine Khaldi     RefUnk *This = impl_from_IUnknown(iface);
2101eb91a739SAmine Khaldi     return InterlockedDecrement(&This->ref);
2102eb91a739SAmine Khaldi }
2103eb91a739SAmine Khaldi 
2104eb91a739SAmine Khaldi static const IUnknownVtbl RefUnkVtbl = {
2105eb91a739SAmine Khaldi     RefUnk_QueryInterface,
2106eb91a739SAmine Khaldi     RefUnk_AddRef,
2107eb91a739SAmine Khaldi     RefUnk_Release
2108eb91a739SAmine Khaldi };
2109eb91a739SAmine Khaldi 
2110eb91a739SAmine Khaldi static RefUnk unk_in = {{&RefUnkVtbl}}, unk_out = {{&RefUnkVtbl}};
2111eb91a739SAmine Khaldi 
2112eb91a739SAmine Khaldi static HANDLE thread_ready;
2113eb91a739SAmine Khaldi 
bsc_thread(void * arg)2114eb91a739SAmine Khaldi static DWORD WINAPI bsc_thread(void *arg)
2115eb91a739SAmine Khaldi {
2116eb91a739SAmine Khaldi     IStream *stream = arg;
2117eb91a739SAmine Khaldi     LARGE_INTEGER zero;
2118eb91a739SAmine Khaldi     MSG msg;
2119eb91a739SAmine Khaldi     HRESULT hres;
2120eb91a739SAmine Khaldi 
2121eb91a739SAmine Khaldi     CoInitialize(NULL);
2122eb91a739SAmine Khaldi 
2123eb91a739SAmine Khaldi     hres = CoMarshalInterface(stream, &IID_IBindStatusCallback, (IUnknown*)&BindStatusCallback,
2124eb91a739SAmine Khaldi                               MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2125eb91a739SAmine Khaldi     ok(hres == S_OK, "CoMarshalInterface failed: %08x\n", hres);
2126eb91a739SAmine Khaldi 
2127eb91a739SAmine Khaldi     zero.QuadPart = 0;
2128eb91a739SAmine Khaldi     hres = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
2129eb91a739SAmine Khaldi     ok(hres == S_OK, "Seek failed: 0x%08x\n", hres);
2130eb91a739SAmine Khaldi 
2131eb91a739SAmine Khaldi     SetEvent(thread_ready);
2132eb91a739SAmine Khaldi 
2133eb91a739SAmine Khaldi     while(GetMessageW(&msg, NULL, 0, 0)) {
2134eb91a739SAmine Khaldi         TranslateMessage(&msg);
2135eb91a739SAmine Khaldi         DispatchMessageW(&msg);
2136eb91a739SAmine Khaldi     }
2137eb91a739SAmine Khaldi 
2138eb91a739SAmine Khaldi     CoUninitialize();
2139eb91a739SAmine Khaldi     return 0;
2140eb91a739SAmine Khaldi }
2141eb91a739SAmine Khaldi 
test_bsc_marshaling(void)2142eb91a739SAmine Khaldi static void test_bsc_marshaling(void)
2143eb91a739SAmine Khaldi {
2144eb91a739SAmine Khaldi     FORMATETC formatetc = {0, NULL, 1, -1, TYMED_ISTREAM};
2145eb91a739SAmine Khaldi     IBindStatusCallbackEx *callbackex;
2146eb91a739SAmine Khaldi     IBindStatusCallback *bsc;
2147eb91a739SAmine Khaldi     BINDINFO bindinfo;
2148eb91a739SAmine Khaldi     IStream *stream, *binding_stream;
2149eb91a739SAmine Khaldi     HANDLE thread;
2150eb91a739SAmine Khaldi     WCHAR *extra_info_out;
2151eb91a739SAmine Khaldi     WCHAR *verb_out;
2152eb91a739SAmine Khaldi     LARGE_INTEGER zero;
2153eb91a739SAmine Khaldi     STGMEDIUM stgmed;
2154eb91a739SAmine Khaldi     void *buf;
2155eb91a739SAmine Khaldi     DWORD bindf;
2156eb91a739SAmine Khaldi     HRESULT hres;
2157eb91a739SAmine Khaldi 
2158eb91a739SAmine Khaldi     hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
2159eb91a739SAmine Khaldi     ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres);
2160eb91a739SAmine Khaldi 
2161eb91a739SAmine Khaldi     thread_ready = CreateEventW(NULL, TRUE, FALSE, NULL);
2162eb91a739SAmine Khaldi     thread = CreateThread(NULL, 0, bsc_thread, stream, 0, NULL);
2163eb91a739SAmine Khaldi     WaitForSingleObject(thread_ready, INFINITE);
2164eb91a739SAmine Khaldi 
2165eb91a739SAmine Khaldi     hres = CoUnmarshalInterface(stream, &IID_IBindStatusCallback, (void**)&bsc);
2166eb91a739SAmine Khaldi     ok(hres == S_OK, "CoUnmarshalInterface failed: %08x\n", hres);
2167eb91a739SAmine Khaldi 
2168eb91a739SAmine Khaldi     hres = CreateStreamOnHGlobal(NULL, TRUE, &binding_stream);
2169eb91a739SAmine Khaldi     ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres);
2170eb91a739SAmine Khaldi     hres = IStream_Write(binding_stream, "xxx", 3, NULL);
2171eb91a739SAmine Khaldi     ok(hres == S_OK, "Write failed: %08x\n", hres);
2172eb91a739SAmine Khaldi 
2173eb91a739SAmine Khaldi     rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2174eb91a739SAmine Khaldi     bindf = 0xdeadbeef;
2175eb91a739SAmine Khaldi 
2176eb91a739SAmine Khaldi     memset(&bindinfo, 0, sizeof(bindinfo));
2177eb91a739SAmine Khaldi     bindinfo.cbSize = sizeof(bindinfo);
2178eb91a739SAmine Khaldi     bindinfo.grfBindInfoF = 12;
2179eb91a739SAmine Khaldi     bindinfo.dwBindVerb = 13;
2180eb91a739SAmine Khaldi     bindinfo.cbstgmedData = 19;
2181eb91a739SAmine Khaldi     bindinfo.dwOptions = 14;
2182eb91a739SAmine Khaldi     bindinfo.dwOptionsFlags = 15;
2183eb91a739SAmine Khaldi     bindinfo.dwCodePage = 16;
2184eb91a739SAmine Khaldi     bindinfo.securityAttributes.nLength = 30;
2185eb91a739SAmine Khaldi     bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0001;
2186eb91a739SAmine Khaldi     bindinfo.securityAttributes.bInheritHandle = 31;
2187eb91a739SAmine Khaldi     bindinfo.iid.Data1 = 17;
2188eb91a739SAmine Khaldi     bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2189eb91a739SAmine Khaldi     bindinfo.dwReserved = 18;
2190eb91a739SAmine Khaldi     bindinfo.stgmedData.pUnkForRelease = &unk_in.IUnknown_iface;
2191eb91a739SAmine Khaldi     unk_in.ref = 1;
2192eb91a739SAmine Khaldi 
2193eb91a739SAmine Khaldi     memset(&rem_bindinfo, 0, sizeof(bindinfo));
2194eb91a739SAmine Khaldi     rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2195eb91a739SAmine Khaldi     rem_bindinfo.szExtraInfo = extra_info_out = a2co("extra info out");
2196eb91a739SAmine Khaldi     rem_bindinfo.grfBindInfoF = 22;
2197eb91a739SAmine Khaldi     rem_bindinfo.dwBindVerb = 23;
2198eb91a739SAmine Khaldi     rem_bindinfo.szCustomVerb = verb_out = a2co("custom verb out");
2199eb91a739SAmine Khaldi     rem_bindinfo.cbstgmedData = 29;
2200eb91a739SAmine Khaldi     rem_bindinfo.dwOptions = 24;
2201eb91a739SAmine Khaldi     rem_bindinfo.dwOptionsFlags = 25;
2202eb91a739SAmine Khaldi     rem_bindinfo.dwCodePage = 16;
2203eb91a739SAmine Khaldi     rem_bindinfo.securityAttributes.nLength = 40;
2204eb91a739SAmine Khaldi     rem_bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0002;
2205eb91a739SAmine Khaldi     rem_bindinfo.securityAttributes.bInheritHandle = 41;
2206eb91a739SAmine Khaldi     rem_bindinfo.iid.Data1 = 27;
2207eb91a739SAmine Khaldi     rem_bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2208eb91a739SAmine Khaldi     rem_bindinfo.dwReserved = 18;
2209eb91a739SAmine Khaldi     rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2210eb91a739SAmine Khaldi     unk_out.ref = 1;
2211eb91a739SAmine Khaldi 
2212eb91a739SAmine Khaldi     hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2213eb91a739SAmine Khaldi     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2214eb91a739SAmine Khaldi     ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2215eb91a739SAmine Khaldi 
2216eb91a739SAmine Khaldi     ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2217eb91a739SAmine Khaldi     ok(!in_bindinfo.szExtraInfo, "szExtraInfo = %s\n", wine_dbgstr_w(in_bindinfo.szExtraInfo));
2218eb91a739SAmine Khaldi     ok(in_bindinfo.grfBindInfoF == 12, "cbSize = %u\n", in_bindinfo.grfBindInfoF);
2219eb91a739SAmine Khaldi     ok(in_bindinfo.dwBindVerb == 13, "dwBindVerb = %u\n", in_bindinfo.dwBindVerb);
2220eb91a739SAmine Khaldi     ok(!in_bindinfo.szCustomVerb, "szCustomVerb = %s\n", wine_dbgstr_w(in_bindinfo.szCustomVerb));
2221eb91a739SAmine Khaldi     ok(in_bindinfo.cbstgmedData == 19, "cbstgmedData = %u\n", in_bindinfo.cbstgmedData);
2222eb91a739SAmine Khaldi     ok(!in_bindinfo.dwOptions, "dwOptions = %u\n", in_bindinfo.dwOptions);
2223eb91a739SAmine Khaldi     ok(!in_bindinfo.dwOptionsFlags, "dwOptionsFlags = %u\n", in_bindinfo.dwOptionsFlags);
2224eb91a739SAmine Khaldi     ok(!in_bindinfo.dwCodePage, "dwCodePage = %u\n", in_bindinfo.dwCodePage);
2225eb91a739SAmine Khaldi     ok(!in_bindinfo.iid.Data1, "iid.Data1 = %u\n", in_bindinfo.iid.Data1);
2226eb91a739SAmine Khaldi     ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2227eb91a739SAmine Khaldi     ok(!in_bindinfo.dwReserved, "dwReserved = %u\n", in_bindinfo.dwReserved);
2228eb91a739SAmine Khaldi     ok(!in_bindinfo.securityAttributes.nLength, "securityAttributes.nLength = %u\n",
2229eb91a739SAmine Khaldi        in_bindinfo.securityAttributes.nLength);
2230eb91a739SAmine Khaldi     ok(!in_bindinfo.securityAttributes.lpSecurityDescriptor,
2231eb91a739SAmine Khaldi        "securityAttributes.lpSecurityDescriptor = %p\n",
2232eb91a739SAmine Khaldi        in_bindinfo.securityAttributes.lpSecurityDescriptor);
2233eb91a739SAmine Khaldi     ok(!in_bindinfo.securityAttributes.bInheritHandle, "securityAttributes.bInheritHandle = %u\n",
2234eb91a739SAmine Khaldi        in_bindinfo.securityAttributes.bInheritHandle);
2235eb91a739SAmine Khaldi     ok(!in_bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2236eb91a739SAmine Khaldi        in_bindinfo.stgmedData.pUnkForRelease);
2237eb91a739SAmine Khaldi 
2238eb91a739SAmine Khaldi     ok(bindinfo.cbSize == sizeof(rem_bindinfo), "cbSize = %u\n", rem_bindinfo.cbSize);
2239eb91a739SAmine Khaldi     ok(!strcmp_wa(bindinfo.szExtraInfo, "extra info out"),
2240eb91a739SAmine Khaldi        "szExtraInfo = %s\n", wine_dbgstr_w(bindinfo.szExtraInfo));
2241eb91a739SAmine Khaldi     ok(bindinfo.grfBindInfoF == 22, "grfBindInfoF = %u\n", rem_bindinfo.grfBindInfoF);
2242eb91a739SAmine Khaldi     ok(bindinfo.dwBindVerb == 23, "dwBindVerb = %u\n", bindinfo.dwBindVerb);
2243eb91a739SAmine Khaldi     ok(bindinfo.szCustomVerb != verb_out, "szCustomVerb == inbuf\n");
2244eb91a739SAmine Khaldi     ok(!strcmp_wa(bindinfo.szCustomVerb, "custom verb out"), "szCustomVerb = %s\n",
2245eb91a739SAmine Khaldi        wine_dbgstr_w(bindinfo.szCustomVerb));
2246eb91a739SAmine Khaldi     ok(bindinfo.cbstgmedData == 29, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2247eb91a739SAmine Khaldi     ok(bindinfo.dwOptions == 24, "dwOptions = %u\n", bindinfo.dwOptions);
2248eb91a739SAmine Khaldi     ok(bindinfo.dwOptionsFlags == 25, "dwOptionsFlags = %u\n", bindinfo.dwOptionsFlags);
2249eb91a739SAmine Khaldi     ok(bindinfo.dwCodePage, "dwCodePage = %u\n", bindinfo.dwCodePage);
2250eb91a739SAmine Khaldi     ok(!bindinfo.iid.Data1, "iid.Data1 = %u\n", bindinfo.iid.Data1);
2251eb91a739SAmine Khaldi     ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2252eb91a739SAmine Khaldi     ok(bindinfo.dwReserved == 18, "dwReserved = %u\n", bindinfo.dwReserved);
2253eb91a739SAmine Khaldi     ok(bindinfo.securityAttributes.nLength == 30, "securityAttributes.nLength = %u\n",
2254eb91a739SAmine Khaldi        bindinfo.securityAttributes.nLength);
2255eb91a739SAmine Khaldi     ok(bindinfo.securityAttributes.lpSecurityDescriptor == (void*)0xdead0001,
2256eb91a739SAmine Khaldi        "securityAttributes.lpSecurityDescriptor = %p\n",
2257eb91a739SAmine Khaldi        bindinfo.securityAttributes.lpSecurityDescriptor);
2258eb91a739SAmine Khaldi     ok(bindinfo.securityAttributes.bInheritHandle == 31, "securityAttributes.bInheritHandle = %u\n",
2259eb91a739SAmine Khaldi        bindinfo.securityAttributes.bInheritHandle);
2260eb91a739SAmine Khaldi     ok(bindinfo.stgmedData.pUnkForRelease == &unk_in.IUnknown_iface, "pUnkForRelease = %p\n",
2261eb91a739SAmine Khaldi        bindinfo.stgmedData.pUnkForRelease);
2262eb91a739SAmine Khaldi     ok(unk_out.ref == 1, "unk_out.ref = %u\n", unk_out.ref);
2263eb91a739SAmine Khaldi 
2264eb91a739SAmine Khaldi     bindinfo.stgmedData.pUnkForRelease = NULL;
2265eb91a739SAmine Khaldi     ReleaseBindInfo(&bindinfo);
2266eb91a739SAmine Khaldi 
2267eb91a739SAmine Khaldi     zero.QuadPart = 0;
2268eb91a739SAmine Khaldi     hres = IStream_Seek(binding_stream, zero, STREAM_SEEK_SET, NULL);
2269eb91a739SAmine Khaldi     ok(hres == S_OK, "Seek failed: 0x%08x\n", hres);
2270eb91a739SAmine Khaldi 
2271eb91a739SAmine Khaldi     /* Return IStream stgmed from GetBindInfo, it's not marshaled back */
2272eb91a739SAmine Khaldi     rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2273eb91a739SAmine Khaldi     bindf = 0xdeadbeef;
2274eb91a739SAmine Khaldi 
2275eb91a739SAmine Khaldi     memset(&bindinfo, 0, sizeof(bindinfo));
2276eb91a739SAmine Khaldi     bindinfo.cbSize = sizeof(bindinfo);
2277eb91a739SAmine Khaldi 
2278eb91a739SAmine Khaldi     memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2279eb91a739SAmine Khaldi     rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2280eb91a739SAmine Khaldi 
2281eb91a739SAmine Khaldi     rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2282eb91a739SAmine Khaldi     rem_bindinfo.stgmedData.u.pstm = binding_stream;
2283eb91a739SAmine Khaldi     rem_bindinfo.cbstgmedData = 3;
2284eb91a739SAmine Khaldi     IStream_AddRef(binding_stream);
2285eb91a739SAmine Khaldi 
2286eb91a739SAmine Khaldi     hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2287eb91a739SAmine Khaldi     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2288eb91a739SAmine Khaldi     ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2289eb91a739SAmine Khaldi 
2290eb91a739SAmine Khaldi     ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2291eb91a739SAmine Khaldi     ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2292eb91a739SAmine Khaldi     ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2293eb91a739SAmine Khaldi        in_bindinfo.stgmedData.tymed);
2294eb91a739SAmine Khaldi 
2295eb91a739SAmine Khaldi     ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2296eb91a739SAmine Khaldi     ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2297eb91a739SAmine Khaldi     ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2298eb91a739SAmine Khaldi        bindinfo.stgmedData.tymed);
2299eb91a739SAmine Khaldi     ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2300eb91a739SAmine Khaldi        bindinfo.stgmedData.u.pstm);
2301eb91a739SAmine Khaldi     ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2302eb91a739SAmine Khaldi        bindinfo.stgmedData.pUnkForRelease);
2303eb91a739SAmine Khaldi     ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2304eb91a739SAmine Khaldi 
2305eb91a739SAmine Khaldi     ReleaseBindInfo(&bindinfo);
2306eb91a739SAmine Khaldi 
2307eb91a739SAmine Khaldi     /* Same, but with pUnkForRelease, it's not marshaled back */
2308eb91a739SAmine Khaldi     rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2309eb91a739SAmine Khaldi     bindf = 0xdeadbeef;
2310eb91a739SAmine Khaldi 
2311eb91a739SAmine Khaldi     memset(&bindinfo, 0, sizeof(bindinfo));
2312eb91a739SAmine Khaldi     bindinfo.cbSize = sizeof(bindinfo);
2313eb91a739SAmine Khaldi 
2314eb91a739SAmine Khaldi     memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2315eb91a739SAmine Khaldi     rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2316eb91a739SAmine Khaldi 
2317eb91a739SAmine Khaldi     rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2318eb91a739SAmine Khaldi     rem_bindinfo.stgmedData.u.pstm = binding_stream;
2319eb91a739SAmine Khaldi     rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2320eb91a739SAmine Khaldi     unk_out.ref = 1;
2321eb91a739SAmine Khaldi     rem_bindinfo.cbstgmedData = 3;
2322eb91a739SAmine Khaldi     IStream_AddRef(binding_stream);
2323eb91a739SAmine Khaldi 
2324eb91a739SAmine Khaldi     hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2325eb91a739SAmine Khaldi     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2326eb91a739SAmine Khaldi     ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2327eb91a739SAmine Khaldi 
2328eb91a739SAmine Khaldi     ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2329eb91a739SAmine Khaldi     ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2330eb91a739SAmine Khaldi     ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2331eb91a739SAmine Khaldi        in_bindinfo.stgmedData.tymed);
2332eb91a739SAmine Khaldi 
2333eb91a739SAmine Khaldi     ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2334eb91a739SAmine Khaldi     ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2335eb91a739SAmine Khaldi     ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2336eb91a739SAmine Khaldi        bindinfo.stgmedData.tymed);
2337eb91a739SAmine Khaldi     ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2338eb91a739SAmine Khaldi        bindinfo.stgmedData.u.pstm);
2339eb91a739SAmine Khaldi     ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2340eb91a739SAmine Khaldi        bindinfo.stgmedData.pUnkForRelease);
2341eb91a739SAmine Khaldi     ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2342eb91a739SAmine Khaldi 
2343eb91a739SAmine Khaldi     ReleaseBindInfo(&bindinfo);
2344eb91a739SAmine Khaldi 
2345eb91a739SAmine Khaldi     /* Return HGLOBAL stgmed from GetBindInfo, it's not marshaled back */
2346eb91a739SAmine Khaldi     rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2347eb91a739SAmine Khaldi     bindf = 0xdeadbeef;
2348eb91a739SAmine Khaldi 
2349eb91a739SAmine Khaldi     memset(&bindinfo, 0, sizeof(bindinfo));
2350eb91a739SAmine Khaldi     bindinfo.cbSize = sizeof(bindinfo);
2351eb91a739SAmine Khaldi 
2352eb91a739SAmine Khaldi     memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2353eb91a739SAmine Khaldi     rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2354eb91a739SAmine Khaldi 
2355eb91a739SAmine Khaldi     rem_bindinfo.stgmedData.tymed = TYMED_HGLOBAL;
2356eb91a739SAmine Khaldi 
23577f95c141SAmine Khaldi     buf = GlobalAlloc(0, 5);
2358eb91a739SAmine Khaldi     strcpy(buf, "test");
2359eb91a739SAmine Khaldi     rem_bindinfo.stgmedData.u.hGlobal = buf;
2360eb91a739SAmine Khaldi     rem_bindinfo.cbstgmedData = 5;
2361eb91a739SAmine Khaldi 
2362eb91a739SAmine Khaldi     hres = IBindStatusCallback_GetBindInfo(bsc, &bindf, &bindinfo);
2363eb91a739SAmine Khaldi     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2364eb91a739SAmine Khaldi     ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2365eb91a739SAmine Khaldi 
2366eb91a739SAmine Khaldi     ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2367eb91a739SAmine Khaldi     ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2368eb91a739SAmine Khaldi     ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2369eb91a739SAmine Khaldi        in_bindinfo.stgmedData.tymed);
2370eb91a739SAmine Khaldi 
2371eb91a739SAmine Khaldi     ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2372eb91a739SAmine Khaldi     ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2373eb91a739SAmine Khaldi     ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2374eb91a739SAmine Khaldi        bindinfo.stgmedData.tymed);
2375eb91a739SAmine Khaldi     ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2376eb91a739SAmine Khaldi        bindinfo.stgmedData.u.pstm);
2377eb91a739SAmine Khaldi     ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2378eb91a739SAmine Khaldi        bindinfo.stgmedData.pUnkForRelease);
2379eb91a739SAmine Khaldi     ok(bindinfo.cbstgmedData == 5, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2380eb91a739SAmine Khaldi 
2381eb91a739SAmine Khaldi     ReleaseBindInfo(&bindinfo);
2382eb91a739SAmine Khaldi 
2383eb91a739SAmine Khaldi     /* Same with GetBindInfoEx */
2384eb91a739SAmine Khaldi     hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackEx, (void**)&callbackex);
2385eb91a739SAmine Khaldi     if(SUCCEEDED(hres)) {
2386eb91a739SAmine Khaldi         DWORD bindf2, reserved;
2387eb91a739SAmine Khaldi 
2388eb91a739SAmine Khaldi         rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2389eb91a739SAmine Khaldi         bindf = bindf2 = reserved = 0xdeadbeef;
2390eb91a739SAmine Khaldi 
2391eb91a739SAmine Khaldi         memset(&bindinfo, 0, sizeof(bindinfo));
2392eb91a739SAmine Khaldi         bindinfo.cbSize = sizeof(bindinfo);
2393eb91a739SAmine Khaldi         bindinfo.grfBindInfoF = 12;
2394eb91a739SAmine Khaldi         bindinfo.dwBindVerb = 13;
2395eb91a739SAmine Khaldi         bindinfo.cbstgmedData = 19;
2396eb91a739SAmine Khaldi         bindinfo.dwOptions = 14;
2397eb91a739SAmine Khaldi         bindinfo.dwOptionsFlags = 15;
2398eb91a739SAmine Khaldi         bindinfo.dwCodePage = 16;
2399eb91a739SAmine Khaldi         bindinfo.securityAttributes.nLength = 30;
2400eb91a739SAmine Khaldi         bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0001;
2401eb91a739SAmine Khaldi         bindinfo.securityAttributes.bInheritHandle = 31;
2402eb91a739SAmine Khaldi         bindinfo.iid.Data1 = 17;
2403eb91a739SAmine Khaldi         bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2404eb91a739SAmine Khaldi         bindinfo.dwReserved = 18;
2405eb91a739SAmine Khaldi         bindinfo.stgmedData.pUnkForRelease = &unk_in.IUnknown_iface;
2406eb91a739SAmine Khaldi         unk_in.ref = 1;
2407eb91a739SAmine Khaldi 
2408eb91a739SAmine Khaldi         memset(&rem_bindinfo, 0, sizeof(bindinfo));
2409eb91a739SAmine Khaldi         rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2410eb91a739SAmine Khaldi         rem_bindinfo.szExtraInfo = extra_info_out = a2co("extra info out");
2411eb91a739SAmine Khaldi         rem_bindinfo.grfBindInfoF = 22;
2412eb91a739SAmine Khaldi         rem_bindinfo.dwBindVerb = 23;
2413eb91a739SAmine Khaldi         rem_bindinfo.szCustomVerb = verb_out = a2co("custom verb out");
2414eb91a739SAmine Khaldi         rem_bindinfo.cbstgmedData = 29;
2415eb91a739SAmine Khaldi         rem_bindinfo.dwOptions = 24;
2416eb91a739SAmine Khaldi         rem_bindinfo.dwOptionsFlags = 25;
2417eb91a739SAmine Khaldi         rem_bindinfo.dwCodePage = 16;
2418eb91a739SAmine Khaldi         rem_bindinfo.securityAttributes.nLength = 40;
2419eb91a739SAmine Khaldi         rem_bindinfo.securityAttributes.lpSecurityDescriptor = (void*)0xdead0002;
2420eb91a739SAmine Khaldi         rem_bindinfo.securityAttributes.bInheritHandle = 41;
2421eb91a739SAmine Khaldi         rem_bindinfo.iid.Data1 = 27;
2422eb91a739SAmine Khaldi         rem_bindinfo.pUnk = (IUnknown*)0xdeadbeef;
2423eb91a739SAmine Khaldi         rem_bindinfo.dwReserved = 18;
2424eb91a739SAmine Khaldi         rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2425eb91a739SAmine Khaldi         unk_out.ref = 1;
2426eb91a739SAmine Khaldi 
2427eb91a739SAmine Khaldi         hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2428eb91a739SAmine Khaldi         ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2429eb91a739SAmine Khaldi         ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2430eb91a739SAmine Khaldi         ok(bindf2 == 11, "bindf2 = %x\n", bindf);
2431eb91a739SAmine Khaldi         ok(reserved == 12, "reserved = %x\n", reserved);
2432eb91a739SAmine Khaldi 
2433eb91a739SAmine Khaldi         ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2434eb91a739SAmine Khaldi         ok(!in_bindinfo.szExtraInfo, "szExtraInfo = %s\n", wine_dbgstr_w(in_bindinfo.szExtraInfo));
2435eb91a739SAmine Khaldi         ok(in_bindinfo.grfBindInfoF == 12, "cbSize = %u\n", in_bindinfo.grfBindInfoF);
2436eb91a739SAmine Khaldi         ok(in_bindinfo.dwBindVerb == 13, "dwBindVerb = %u\n", in_bindinfo.dwBindVerb);
2437eb91a739SAmine Khaldi         ok(!in_bindinfo.szCustomVerb, "szCustomVerb = %s\n", wine_dbgstr_w(in_bindinfo.szCustomVerb));
2438eb91a739SAmine Khaldi         ok(in_bindinfo.cbstgmedData == 19, "cbstgmedData = %u\n", in_bindinfo.cbstgmedData);
2439eb91a739SAmine Khaldi         ok(!in_bindinfo.dwOptions, "dwOptions = %u\n", in_bindinfo.dwOptions);
2440eb91a739SAmine Khaldi         ok(!in_bindinfo.dwOptionsFlags, "dwOptionsFlags = %u\n", in_bindinfo.dwOptionsFlags);
2441eb91a739SAmine Khaldi         ok(!in_bindinfo.dwCodePage, "dwCodePage = %u\n", in_bindinfo.dwCodePage);
2442eb91a739SAmine Khaldi         ok(!in_bindinfo.iid.Data1, "iid.Data1 = %u\n", in_bindinfo.iid.Data1);
2443eb91a739SAmine Khaldi         ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2444eb91a739SAmine Khaldi         ok(!in_bindinfo.dwReserved, "dwReserved = %u\n", in_bindinfo.dwReserved);
2445eb91a739SAmine Khaldi         ok(!in_bindinfo.securityAttributes.nLength, "securityAttributes.nLength = %u\n",
2446eb91a739SAmine Khaldi            in_bindinfo.securityAttributes.nLength);
2447eb91a739SAmine Khaldi         ok(!in_bindinfo.securityAttributes.lpSecurityDescriptor,
2448eb91a739SAmine Khaldi            "securityAttributes.lpSecurityDescriptor = %p\n",
2449eb91a739SAmine Khaldi            in_bindinfo.securityAttributes.lpSecurityDescriptor);
2450eb91a739SAmine Khaldi         ok(!in_bindinfo.securityAttributes.bInheritHandle, "securityAttributes.bInheritHandle = %u\n",
2451eb91a739SAmine Khaldi            in_bindinfo.securityAttributes.bInheritHandle);
2452eb91a739SAmine Khaldi         ok(!in_bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2453eb91a739SAmine Khaldi            in_bindinfo.stgmedData.pUnkForRelease);
2454eb91a739SAmine Khaldi 
2455eb91a739SAmine Khaldi         ok(bindinfo.cbSize == sizeof(rem_bindinfo), "cbSize = %u\n", rem_bindinfo.cbSize);
2456eb91a739SAmine Khaldi         ok(!strcmp_wa(bindinfo.szExtraInfo, "extra info out"),
2457eb91a739SAmine Khaldi            "szExtraInfo = %s\n", wine_dbgstr_w(bindinfo.szExtraInfo));
2458eb91a739SAmine Khaldi         ok(bindinfo.grfBindInfoF == 22, "grfBindInfoF = %u\n", rem_bindinfo.grfBindInfoF);
2459eb91a739SAmine Khaldi         ok(bindinfo.dwBindVerb == 23, "dwBindVerb = %u\n", bindinfo.dwBindVerb);
2460eb91a739SAmine Khaldi         ok(bindinfo.szCustomVerb != verb_out, "szCustomVerb == inbuf\n");
2461eb91a739SAmine Khaldi         ok(!strcmp_wa(bindinfo.szCustomVerb, "custom verb out"), "szCustomVerb = %s\n",
2462eb91a739SAmine Khaldi            wine_dbgstr_w(bindinfo.szCustomVerb));
2463eb91a739SAmine Khaldi         ok(bindinfo.cbstgmedData == 29, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2464eb91a739SAmine Khaldi         ok(bindinfo.dwOptions == 24, "dwOptions = %u\n", bindinfo.dwOptions);
2465eb91a739SAmine Khaldi         ok(bindinfo.dwOptionsFlags == 25, "dwOptionsFlags = %u\n", bindinfo.dwOptionsFlags);
2466eb91a739SAmine Khaldi         ok(bindinfo.dwCodePage, "dwCodePage = %u\n", bindinfo.dwCodePage);
2467eb91a739SAmine Khaldi         ok(!bindinfo.iid.Data1, "iid.Data1 = %u\n", bindinfo.iid.Data1);
2468eb91a739SAmine Khaldi         ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2469eb91a739SAmine Khaldi         ok(bindinfo.dwReserved == 18, "dwReserved = %u\n", bindinfo.dwReserved);
2470eb91a739SAmine Khaldi         ok(bindinfo.securityAttributes.nLength == 30, "securityAttributes.nLength = %u\n",
2471eb91a739SAmine Khaldi            bindinfo.securityAttributes.nLength);
2472eb91a739SAmine Khaldi         ok(bindinfo.securityAttributes.lpSecurityDescriptor == (void*)0xdead0001,
2473eb91a739SAmine Khaldi            "securityAttributes.lpSecurityDescriptor = %p\n",
2474eb91a739SAmine Khaldi            bindinfo.securityAttributes.lpSecurityDescriptor);
2475eb91a739SAmine Khaldi         ok(bindinfo.securityAttributes.bInheritHandle == 31, "securityAttributes.bInheritHandle = %u\n",
2476eb91a739SAmine Khaldi            bindinfo.securityAttributes.bInheritHandle);
2477eb91a739SAmine Khaldi         ok(bindinfo.stgmedData.pUnkForRelease == &unk_in.IUnknown_iface, "pUnkForRelease = %p\n",
2478eb91a739SAmine Khaldi            bindinfo.stgmedData.pUnkForRelease);
2479eb91a739SAmine Khaldi         ok(unk_out.ref == 1, "unk_out.ref = %u\n", unk_out.ref);
2480eb91a739SAmine Khaldi 
2481eb91a739SAmine Khaldi         bindinfo.stgmedData.pUnkForRelease = NULL;
2482eb91a739SAmine Khaldi         ReleaseBindInfo(&bindinfo);
2483eb91a739SAmine Khaldi 
2484eb91a739SAmine Khaldi         zero.QuadPart = 0;
2485eb91a739SAmine Khaldi         hres = IStream_Seek(binding_stream, zero, STREAM_SEEK_SET, NULL);
2486eb91a739SAmine Khaldi         ok(hres == S_OK, "Seek failed: 0x%08x\n", hres);
2487eb91a739SAmine Khaldi 
2488eb91a739SAmine Khaldi         /* Return IStream stgmed from GetBindInfoEx, it's not marshaled back */
2489eb91a739SAmine Khaldi         rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2490eb91a739SAmine Khaldi         bindf = bindf2 = reserved = 0xdeadbeef;
2491eb91a739SAmine Khaldi 
2492eb91a739SAmine Khaldi         memset(&bindinfo, 0, sizeof(bindinfo));
2493eb91a739SAmine Khaldi         bindinfo.cbSize = sizeof(bindinfo);
2494eb91a739SAmine Khaldi 
2495eb91a739SAmine Khaldi         memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2496eb91a739SAmine Khaldi         rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2497eb91a739SAmine Khaldi 
2498eb91a739SAmine Khaldi         rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2499eb91a739SAmine Khaldi         rem_bindinfo.stgmedData.u.pstm = binding_stream;
2500eb91a739SAmine Khaldi         rem_bindinfo.cbstgmedData = 3;
2501eb91a739SAmine Khaldi         IStream_AddRef(binding_stream);
2502eb91a739SAmine Khaldi 
2503eb91a739SAmine Khaldi         hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2504eb91a739SAmine Khaldi         ok(hres == S_OK, "GetBindInfoEx failed: %08x\n", hres);
2505eb91a739SAmine Khaldi         ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2506eb91a739SAmine Khaldi 
2507eb91a739SAmine Khaldi         ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2508eb91a739SAmine Khaldi         ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2509eb91a739SAmine Khaldi         ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2510eb91a739SAmine Khaldi            in_bindinfo.stgmedData.tymed);
2511eb91a739SAmine Khaldi 
2512eb91a739SAmine Khaldi         ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2513eb91a739SAmine Khaldi         ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2514eb91a739SAmine Khaldi         ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2515eb91a739SAmine Khaldi            bindinfo.stgmedData.tymed);
2516eb91a739SAmine Khaldi         ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2517eb91a739SAmine Khaldi            bindinfo.stgmedData.u.pstm);
2518eb91a739SAmine Khaldi         ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2519eb91a739SAmine Khaldi            bindinfo.stgmedData.pUnkForRelease);
2520eb91a739SAmine Khaldi         ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2521eb91a739SAmine Khaldi 
2522eb91a739SAmine Khaldi         ReleaseBindInfo(&bindinfo);
2523eb91a739SAmine Khaldi 
2524eb91a739SAmine Khaldi         /* Same, but with pUnkForRelease, it's not marshaled back */
2525eb91a739SAmine Khaldi         rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2526eb91a739SAmine Khaldi         bindf = bindf2 = reserved = 0xdeadbeef;
2527eb91a739SAmine Khaldi 
2528eb91a739SAmine Khaldi         memset(&bindinfo, 0, sizeof(bindinfo));
2529eb91a739SAmine Khaldi         bindinfo.cbSize = sizeof(bindinfo);
2530eb91a739SAmine Khaldi 
2531eb91a739SAmine Khaldi         memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2532eb91a739SAmine Khaldi         rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2533eb91a739SAmine Khaldi 
2534eb91a739SAmine Khaldi         rem_bindinfo.stgmedData.tymed = TYMED_ISTREAM;
2535eb91a739SAmine Khaldi         rem_bindinfo.stgmedData.u.pstm = binding_stream;
2536eb91a739SAmine Khaldi         rem_bindinfo.stgmedData.pUnkForRelease = &unk_out.IUnknown_iface;
2537eb91a739SAmine Khaldi         unk_out.ref = 1;
2538eb91a739SAmine Khaldi         rem_bindinfo.cbstgmedData = 3;
2539eb91a739SAmine Khaldi         IStream_AddRef(binding_stream);
2540eb91a739SAmine Khaldi 
2541eb91a739SAmine Khaldi         hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2542eb91a739SAmine Khaldi         ok(hres == S_OK, "GetBindInfoEx failed: %08x\n", hres);
2543eb91a739SAmine Khaldi         ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2544eb91a739SAmine Khaldi 
2545eb91a739SAmine Khaldi         ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2546eb91a739SAmine Khaldi         ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2547eb91a739SAmine Khaldi         ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2548eb91a739SAmine Khaldi            in_bindinfo.stgmedData.tymed);
2549eb91a739SAmine Khaldi 
2550eb91a739SAmine Khaldi         ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2551eb91a739SAmine Khaldi         ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2552eb91a739SAmine Khaldi         ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2553eb91a739SAmine Khaldi            bindinfo.stgmedData.tymed);
2554eb91a739SAmine Khaldi         ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2555eb91a739SAmine Khaldi            bindinfo.stgmedData.u.pstm);
2556eb91a739SAmine Khaldi         ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2557eb91a739SAmine Khaldi            bindinfo.stgmedData.pUnkForRelease);
2558eb91a739SAmine Khaldi         ok(bindinfo.cbstgmedData == 3, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2559eb91a739SAmine Khaldi 
2560eb91a739SAmine Khaldi         ReleaseBindInfo(&bindinfo);
2561eb91a739SAmine Khaldi 
2562eb91a739SAmine Khaldi         /* Return HGLOBAL stgmed from GetBindInfoEx, it's not marshaled back */
2563eb91a739SAmine Khaldi         rem_bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
2564eb91a739SAmine Khaldi         bindf = bindf2 = reserved = 0xdeadbeef;
2565eb91a739SAmine Khaldi 
2566eb91a739SAmine Khaldi         memset(&bindinfo, 0, sizeof(bindinfo));
2567eb91a739SAmine Khaldi         bindinfo.cbSize = sizeof(bindinfo);
2568eb91a739SAmine Khaldi 
2569eb91a739SAmine Khaldi         memset(&rem_bindinfo, 0, sizeof(rem_bindinfo));
2570eb91a739SAmine Khaldi         rem_bindinfo.cbSize = sizeof(rem_bindinfo);
2571eb91a739SAmine Khaldi 
2572eb91a739SAmine Khaldi         rem_bindinfo.stgmedData.tymed = TYMED_HGLOBAL;
2573eb91a739SAmine Khaldi 
25747f95c141SAmine Khaldi         buf = GlobalAlloc(0, 5);
2575eb91a739SAmine Khaldi         strcpy(buf, "test");
2576eb91a739SAmine Khaldi         rem_bindinfo.stgmedData.u.hGlobal = buf;
2577eb91a739SAmine Khaldi         rem_bindinfo.cbstgmedData = 5;
2578eb91a739SAmine Khaldi 
2579eb91a739SAmine Khaldi         hres = IBindStatusCallbackEx_GetBindInfoEx(callbackex, &bindf, &bindinfo, &bindf2, &reserved);
2580eb91a739SAmine Khaldi         ok(hres == S_OK, "GetBindInfoEx failed: %08x\n", hres);
2581eb91a739SAmine Khaldi         ok(bindf == rem_bindf, "bindf = %x, expected %x\n", bindf, rem_bindf);
2582eb91a739SAmine Khaldi 
2583eb91a739SAmine Khaldi         ok(in_bindinfo.cbSize == sizeof(in_bindinfo), "cbSize = %u\n", in_bindinfo.cbSize);
2584eb91a739SAmine Khaldi         ok(!in_bindinfo.pUnk, "pUnk = %p\n", in_bindinfo.pUnk);
2585eb91a739SAmine Khaldi         ok(in_bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2586eb91a739SAmine Khaldi            in_bindinfo.stgmedData.tymed);
2587eb91a739SAmine Khaldi 
2588eb91a739SAmine Khaldi         ok(bindinfo.cbSize == sizeof(bindinfo), "cbSize = %u\n", bindinfo.cbSize);
2589eb91a739SAmine Khaldi         ok(!bindinfo.pUnk, "pUnk = %p\n", bindinfo.pUnk);
2590eb91a739SAmine Khaldi         ok(bindinfo.stgmedData.tymed == TYMED_NULL, "tymed = %u\n",
2591eb91a739SAmine Khaldi            bindinfo.stgmedData.tymed);
2592eb91a739SAmine Khaldi         ok(!bindinfo.stgmedData.u.pstm, "stm = %p\n",
2593eb91a739SAmine Khaldi            bindinfo.stgmedData.u.pstm);
2594eb91a739SAmine Khaldi         ok(!bindinfo.stgmedData.pUnkForRelease, "pUnkForRelease = %p\n",
2595eb91a739SAmine Khaldi            bindinfo.stgmedData.pUnkForRelease);
2596eb91a739SAmine Khaldi         ok(bindinfo.cbstgmedData == 5, "cbstgmedData = %u\n", bindinfo.cbstgmedData);
2597eb91a739SAmine Khaldi 
2598eb91a739SAmine Khaldi         ReleaseBindInfo(&bindinfo);
2599eb91a739SAmine Khaldi 
2600eb91a739SAmine Khaldi         IBindStatusCallbackEx_Release(callbackex);
2601eb91a739SAmine Khaldi     }else {
2602eb91a739SAmine Khaldi         win_skip("IBindStatusCallbackEx not supported\n");
2603eb91a739SAmine Khaldi     }
2604eb91a739SAmine Khaldi 
2605eb91a739SAmine Khaldi     /* Test marshaling stgmed from OnDataAvailable */
2606eb91a739SAmine Khaldi     memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2607eb91a739SAmine Khaldi     stgmed.tymed = TYMED_ISTREAM;
2608eb91a739SAmine Khaldi     stgmed.u.pstm = binding_stream;
2609eb91a739SAmine Khaldi     stgmed.pUnkForRelease = NULL;
2610eb91a739SAmine Khaldi 
2611eb91a739SAmine Khaldi     hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2612eb91a739SAmine Khaldi     ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2613eb91a739SAmine Khaldi 
2614eb91a739SAmine Khaldi     ok(in_stgmed.tymed == TYMED_ISTREAM, "tymed = %u\n", in_stgmed.tymed);
2615eb91a739SAmine Khaldi     ok(in_stgmed.u.pstm != NULL, "pstm = NULL\n");
2616eb91a739SAmine Khaldi     ok(!in_stgmed.pUnkForRelease, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2617eb91a739SAmine Khaldi 
2618eb91a739SAmine Khaldi     /* OnDataAvailable with both IStream and pUnkForRelease */
2619eb91a739SAmine Khaldi     memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2620eb91a739SAmine Khaldi     stgmed.tymed = TYMED_ISTREAM;
2621eb91a739SAmine Khaldi     stgmed.u.pstm = binding_stream;
2622eb91a739SAmine Khaldi     stgmed.pUnkForRelease = &unk_in.IUnknown_iface;
2623eb91a739SAmine Khaldi     unk_in.ref = 1;
2624eb91a739SAmine Khaldi 
2625eb91a739SAmine Khaldi     hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2626eb91a739SAmine Khaldi     ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2627eb91a739SAmine Khaldi 
2628eb91a739SAmine Khaldi     ok(in_stgmed.tymed == TYMED_ISTREAM, "tymed = %u\n", in_stgmed.tymed);
2629eb91a739SAmine Khaldi     ok(in_stgmed.u.pstm != NULL, "pstm = NULL\n");
2630eb91a739SAmine Khaldi     ok(in_stgmed.pUnkForRelease != NULL, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2631eb91a739SAmine Khaldi     ok(unk_in.ref > 1, "ref = %u\n", unk_in.ref);
2632eb91a739SAmine Khaldi 
2633eb91a739SAmine Khaldi     /* OnDataAvailable with TYMED_ISTREAM, but NULL stream */
2634eb91a739SAmine Khaldi     memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2635eb91a739SAmine Khaldi     stgmed.tymed = TYMED_ISTREAM;
2636eb91a739SAmine Khaldi     stgmed.u.pstm = binding_stream;
2637eb91a739SAmine Khaldi     stgmed.pUnkForRelease = NULL;
2638eb91a739SAmine Khaldi 
2639eb91a739SAmine Khaldi     hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2640eb91a739SAmine Khaldi     ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2641eb91a739SAmine Khaldi 
2642eb91a739SAmine Khaldi     ok(in_stgmed.tymed == TYMED_ISTREAM, "tymed = %u\n", in_stgmed.tymed);
2643eb91a739SAmine Khaldi     ok(in_stgmed.u.pstm != NULL, "pstm = NULL\n");
2644eb91a739SAmine Khaldi     ok(!in_stgmed.pUnkForRelease, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2645eb91a739SAmine Khaldi 
2646eb91a739SAmine Khaldi     /* OnDataAvailable with TYMED_NULL and pUnkForRelease */
2647eb91a739SAmine Khaldi     memset(&in_stgmed, 0xcc, sizeof(in_stgmed));
2648eb91a739SAmine Khaldi     stgmed.tymed = TYMED_NULL;
2649eb91a739SAmine Khaldi     stgmed.u.pstm = binding_stream;
2650eb91a739SAmine Khaldi     stgmed.pUnkForRelease = &unk_in.IUnknown_iface;
2651eb91a739SAmine Khaldi     unk_in.ref = 1;
2652eb91a739SAmine Khaldi 
2653eb91a739SAmine Khaldi     hres = IBindStatusCallback_OnDataAvailable(bsc, 1, 10, &formatetc, &stgmed);
2654eb91a739SAmine Khaldi     ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
2655eb91a739SAmine Khaldi 
2656eb91a739SAmine Khaldi     ok(in_stgmed.tymed == TYMED_NULL, "tymed = %u\n", in_stgmed.tymed);
2657eb91a739SAmine Khaldi     ok(!in_stgmed.u.pstm, "pstm != NULL\n");
2658eb91a739SAmine Khaldi     ok(in_stgmed.pUnkForRelease != NULL, "pUnkForRelease = %p\n", in_stgmed.pUnkForRelease);
2659eb91a739SAmine Khaldi     ok(unk_in.ref == 1, "ref = %u\n", unk_in.ref);
2660eb91a739SAmine Khaldi 
2661eb91a739SAmine Khaldi     IStream_Release(binding_stream);
2662eb91a739SAmine Khaldi     IBindStatusCallback_Release(bsc);
2663eb91a739SAmine Khaldi 
2664eb91a739SAmine Khaldi     TerminateThread(thread, 0);
2665eb91a739SAmine Khaldi }
2666eb91a739SAmine Khaldi 
START_TEST(misc)2667c2c66affSColin Finck START_TEST(misc)
2668c2c66affSColin Finck {
2669c2c66affSColin Finck     HMODULE hurlmon;
2670c2c66affSColin Finck     int argc;
2671c2c66affSColin Finck     char **argv;
2672c2c66affSColin Finck 
2673c2c66affSColin Finck     argc = winetest_get_mainargs(&argv);
2674c2c66affSColin Finck 
2675c2c66affSColin Finck     hurlmon = GetModuleHandleA("urlmon.dll");
2676c2c66affSColin Finck     pCoInternetCompareUrl = (void *) GetProcAddress(hurlmon, "CoInternetCompareUrl");
2677c2c66affSColin Finck     pCoInternetGetSecurityUrl = (void*) GetProcAddress(hurlmon, "CoInternetGetSecurityUrl");
2678c2c66affSColin Finck     pCoInternetGetSession = (void*) GetProcAddress(hurlmon, "CoInternetGetSession");
2679c2c66affSColin Finck     pCoInternetParseUrl = (void*) GetProcAddress(hurlmon, "CoInternetParseUrl");
2680c2c66affSColin Finck     pCoInternetQueryInfo = (void*) GetProcAddress(hurlmon, "CoInternetQueryInfo");
2681c2c66affSColin Finck     pCopyStgMedium = (void*) GetProcAddress(hurlmon, "CopyStgMedium");
2682c2c66affSColin Finck     pCopyBindInfo = (void*) GetProcAddress(hurlmon, "CopyBindInfo");
2683c2c66affSColin Finck     pFindMimeFromData = (void*) GetProcAddress(hurlmon, "FindMimeFromData");
2684c2c66affSColin Finck     pObtainUserAgentString = (void*) GetProcAddress(hurlmon, "ObtainUserAgentString");
2685c2c66affSColin Finck     pReleaseBindInfo = (void*) GetProcAddress(hurlmon, "ReleaseBindInfo");
2686c2c66affSColin Finck     pUrlMkGetSessionOption = (void*) GetProcAddress(hurlmon, "UrlMkGetSessionOption");
2687c2c66affSColin Finck     pCompareSecurityIds = (void*) GetProcAddress(hurlmon, "CompareSecurityIds");
2688c2c66affSColin Finck     pCoInternetIsFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetIsFeatureEnabled");
2689c2c66affSColin Finck     pCoInternetSetFeatureEnabled = (void*) GetProcAddress(hurlmon, "CoInternetSetFeatureEnabled");
2690c2c66affSColin Finck     pIEInstallScope = (void*) GetProcAddress(hurlmon, "IEInstallScope");
2691c2c66affSColin Finck 
2692c2c66affSColin Finck     if (!pCoInternetCompareUrl || !pCoInternetGetSecurityUrl ||
2693c2c66affSColin Finck         !pCoInternetGetSession || !pCoInternetParseUrl || !pCompareSecurityIds) {
2694c2c66affSColin Finck         win_skip("Various needed functions not present, too old IE\n");
2695c2c66affSColin Finck         return;
2696c2c66affSColin Finck     }
2697c2c66affSColin Finck 
2698c2c66affSColin Finck     OleInitialize(NULL);
2699c2c66affSColin Finck 
2700c2c66affSColin Finck     if(argc <= 2 || strcmp(argv[2], "internet_features")) {
2701c2c66affSColin Finck         register_protocols();
2702c2c66affSColin Finck 
2703c2c66affSColin Finck         test_CreateFormatEnum();
2704c2c66affSColin Finck         test_RegisterFormatEnumerator();
2705c2c66affSColin Finck         test_CoInternetParseUrl();
2706c2c66affSColin Finck         test_CoInternetCompareUrl();
2707c2c66affSColin Finck         test_CoInternetQueryInfo();
2708c2c66affSColin Finck         test_FindMimeFromData();
2709c2c66affSColin Finck         test_NameSpace();
2710c2c66affSColin Finck         test_MimeFilter();
2711c2c66affSColin Finck         test_ReleaseBindInfo();
2712c2c66affSColin Finck         test_CopyStgMedium();
2713c2c66affSColin Finck         test_CopyBindInfo();
2714c2c66affSColin Finck         test_UrlMkGetSessionOption();
2715c2c66affSColin Finck         test_user_agent();
2716c2c66affSColin Finck         test_MkParseDisplayNameEx();
2717c2c66affSColin Finck         test_IsValidURL();
2718eb91a739SAmine Khaldi         test_bsc_marshaling();
2719c2c66affSColin Finck     }
2720c2c66affSColin Finck 
2721c2c66affSColin Finck     test_internet_features();
2722c2c66affSColin Finck 
2723c2c66affSColin Finck     OleUninitialize();
2724c2c66affSColin Finck }
2725