Make CryptImport/ExportPublicKeyInfoEx behave the way MSDN describes
[wine/gsoc-2012-control.git] / dlls / urlmon / tests / url.c
blobe65dff6c6683f805c81a58e62514ab89e137112a
1 /*
2 * UrlMon URL tests
4 * Copyright 2004 Kevin Koltzau
5 * Copyright 2004 Jacek Caban
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdarg.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "urlmon.h"
30 #include "wine/test.h"
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35 #define SET_EXPECT(func) \
36 expect_ ## func = TRUE
38 #define CHECK_EXPECT(func) \
39 ok(expect_ ##func, "unexpected call\n"); \
40 expect_ ## func = FALSE; \
41 called_ ## func = TRUE
43 #define CHECK_EXPECT2(func) \
44 ok(expect_ ##func, "unexpected call\n"); \
45 called_ ## func = TRUE
47 #define CHECK_CALLED(func) \
48 ok(called_ ## func, "expected " #func "\n"); \
49 expect_ ## func = called_ ## func = FALSE
51 DEFINE_EXPECT(GetBindInfo);
52 DEFINE_EXPECT(OnStartBinding);
53 DEFINE_EXPECT(OnProgress_FINDINGRESOURCE);
54 DEFINE_EXPECT(OnProgress_CONNECTING);
55 DEFINE_EXPECT(OnProgress_SENDINGREQUEST);
56 DEFINE_EXPECT(OnProgress_MIMETYPEAVAILABLE);
57 DEFINE_EXPECT(OnProgress_BEGINDOWNLOADDATA);
58 DEFINE_EXPECT(OnProgress_DOWNLOADINGDATA);
59 DEFINE_EXPECT(OnProgress_ENDDOWNLOADDATA);
60 DEFINE_EXPECT(OnStopBinding);
61 DEFINE_EXPECT(OnDataAvailable);
63 static const WCHAR TEST_URL_1[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/','\0'};
64 static const WCHAR TEST_PART_URL_1[] = {'/','t','e','s','t','/','\0'};
66 static const WCHAR WINE_ABOUT_URL[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
67 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0};
68 static BOOL stopped_binding = FALSE;
70 static void test_CreateURLMoniker(LPCWSTR url1, LPCWSTR url2)
72 HRESULT hr;
73 IMoniker *mon1 = NULL;
74 IMoniker *mon2 = NULL;
76 hr = CreateURLMoniker(NULL, url1, &mon1);
77 ok(SUCCEEDED(hr), "failed to create moniker: 0x%08lx\n", hr);
78 if(SUCCEEDED(hr)) {
79 hr = CreateURLMoniker(mon1, url2, &mon2);
80 ok(SUCCEEDED(hr), "failed to create moniker: 0x%08lx\n", hr);
82 if(mon1) IMoniker_Release(mon1);
83 if(mon2) IMoniker_Release(mon2);
86 static void test_create(void)
88 test_CreateURLMoniker(TEST_URL_1, TEST_PART_URL_1);
91 typedef struct {
92 const IBindStatusCallbackVtbl *lpVtbl;
93 LONG ref;
94 IBinding *pbind;
95 IStream *pstr;
96 } statusclb;
98 static HRESULT WINAPI statusclb_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppvObject)
100 return E_NOINTERFACE;
103 static ULONG WINAPI statusclb_AddRef(IBindStatusCallback *iface)
105 return InterlockedIncrement(&((statusclb*)iface)->ref);
108 static ULONG WINAPI statusclb_Release(IBindStatusCallback *iface)
110 statusclb *This = (statusclb*)iface;
111 ULONG ref;
112 ref = InterlockedDecrement(&This->ref);
113 if(!ref)
114 HeapFree(GetProcessHeap(), 0, This);
115 return ref;
118 static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
119 IBinding *pib)
121 statusclb *This = (statusclb*)iface;
122 HRESULT hres;
123 IMoniker *mon;
125 CHECK_EXPECT(OnStartBinding);
127 This->pbind = pib;
128 ok(pib != NULL, "pib should not be NULL\n");
129 if(pib)
130 IBinding_AddRef(pib);
132 hres = IBinding_QueryInterface(pib, &IID_IMoniker, (void**)&mon);
133 ok(hres == E_NOINTERFACE, "IBinding should not have IMoniker interface\n");
134 if(SUCCEEDED(hres))
135 IMoniker_Release(mon);
137 return S_OK;
140 static HRESULT WINAPI statusclb_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
142 ok(0, "unexpected call\n");
143 return E_NOTIMPL;
146 static HRESULT WINAPI statusclb_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
148 ok(0, "unexpected call\n");
149 return E_NOTIMPL;
152 static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
153 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
155 switch(ulStatusCode) {
156 case BINDSTATUS_FINDINGRESOURCE:
157 CHECK_EXPECT(OnProgress_FINDINGRESOURCE);
158 break;
159 case BINDSTATUS_CONNECTING:
160 CHECK_EXPECT(OnProgress_CONNECTING);
161 break;
162 case BINDSTATUS_SENDINGREQUEST:
163 CHECK_EXPECT(OnProgress_SENDINGREQUEST);
164 break;
165 case BINDSTATUS_MIMETYPEAVAILABLE:
166 CHECK_EXPECT(OnProgress_MIMETYPEAVAILABLE);
167 break;
168 case BINDSTATUS_BEGINDOWNLOADDATA:
169 CHECK_EXPECT(OnProgress_BEGINDOWNLOADDATA);
170 break;
171 case BINDSTATUS_DOWNLOADINGDATA:
172 CHECK_EXPECT2(OnProgress_DOWNLOADINGDATA);
173 break;
174 case BINDSTATUS_ENDDOWNLOADDATA:
175 CHECK_EXPECT(OnProgress_ENDDOWNLOADDATA);
176 break;
177 default:
178 todo_wine { ok(0, "unexpexted code %ld\n", ulStatusCode); }
180 return S_OK;
183 static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
185 statusclb *This = (statusclb*)iface;
187 CHECK_EXPECT(OnStopBinding);
189 ok(SUCCEEDED(hresult), "Download failed: %08lx\n", hresult);
190 ok(szError == NULL, "szError should be NULL\n");
191 stopped_binding = TRUE;
192 IBinding_Release(This->pbind);
193 ok(This->pstr != NULL, "pstr should not be NULL here\n");
194 if(This->pstr)
195 IStream_Release(This->pstr);
197 return S_OK;
200 static HRESULT WINAPI statusclb_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
202 DWORD cbSize;
204 CHECK_EXPECT(GetBindInfo);
206 *grfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
207 cbSize = pbindinfo->cbSize;
208 memset(pbindinfo, 0, cbSize);
209 pbindinfo->cbSize = cbSize;
211 return S_OK;
214 static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF, DWORD dwSize,
215 FORMATETC* pformatetc, STGMEDIUM* pstgmed)
217 statusclb *This = (statusclb*)iface;
218 HRESULT hres;
219 DWORD readed;
220 BYTE buf[512];
222 CHECK_EXPECT2(OnDataAvailable);
224 if(!This->pstr) {
225 ok(grfBSCF & BSCF_FIRSTDATANOTIFICATION, "pstr should be set when BSCF_FIRSTDATANOTIFICATION\n");
226 This->pstr = U(*pstgmed).pstm;
227 IStream_AddRef(This->pstr);
228 ok(This->pstr != NULL, "pstr should not be NULL here\n");
231 do hres = IStream_Read(This->pstr, buf, 512, &readed);
232 while(hres == S_OK);
233 ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08lx\n", hres);
235 return S_OK;
238 static HRESULT WINAPI statusclb_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
240 ok(0, "unexpected call\n");
241 return E_NOTIMPL;
244 static const IBindStatusCallbackVtbl statusclbVtbl = {
245 statusclb_QueryInterface,
246 statusclb_AddRef,
247 statusclb_Release,
248 statusclb_OnStartBinding,
249 statusclb_GetPriority,
250 statusclb_OnLowResource,
251 statusclb_OnProgress,
252 statusclb_OnStopBinding,
253 statusclb_GetBindInfo,
254 statusclb_OnDataAvailable,
255 statusclb_OnObjectAvailable
258 static IBindStatusCallback* statusclb_create(void)
260 statusclb *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(statusclb));
261 ret->lpVtbl = &statusclbVtbl;
262 ret->ref = 1;
263 ret->pbind = NULL;
264 ret->pstr = NULL;
265 return (IBindStatusCallback*)ret;
268 static void test_CreateAsyncBindCtx(void)
270 IBindCtx *bctx = (IBindCtx*)0x0ff00ff0;
271 HRESULT hres;
272 ULONG ref;
273 BIND_OPTS bindopts;
274 IBindStatusCallback *bsc = statusclb_create();
276 hres = CreateAsyncBindCtx(0, NULL, NULL, &bctx);
277 ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08lx\n", hres);
278 ok(bctx == (IBindCtx*)0x0ff00ff0, "bctx should not be changed\n");
280 hres = CreateAsyncBindCtx(0, NULL, NULL, NULL);
281 ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08lx\n", hres);
283 hres = CreateAsyncBindCtx(0, bsc, NULL, &bctx);
284 ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08lx\n", hres);
285 if(FAILED(hres)) {
286 IBindStatusCallback_Release(bsc);
287 return;
290 bindopts.cbStruct = sizeof(bindopts);
291 hres = IBindCtx_GetBindOptions(bctx, &bindopts);
292 ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08lx\n", hres);
293 ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
294 "bindopts.grfFlags = %08lx, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
295 ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
296 "bindopts.grfMode = %08lx, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
297 bindopts.grfMode);
298 ok(bindopts.dwTickCountDeadline == 0,
299 "bindopts.dwTickCountDeadline = %08lx, expected: 0\n", bindopts.dwTickCountDeadline);
301 ref = IBindCtx_Release(bctx);
302 ok(ref == 0, "bctx should be destroyed here\n");
303 ref = IBindStatusCallback_Release(bsc);
304 ok(ref == 0, "bsc should be destroyed here\n");
307 static void test_CreateAsyncBindCtxEx(void)
309 IBindCtx *bctx = NULL, *bctx_arg = NULL;
310 IBindStatusCallback *bsc = statusclb_create();
311 BIND_OPTS bindopts;
312 HRESULT hres;
314 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, NULL, 0);
315 ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed: %08lx, expected E_INVALIDARG\n", hres);
317 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
318 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08lx\n", hres);
320 if(SUCCEEDED(hres)) {
321 bindopts.cbStruct = sizeof(bindopts);
322 hres = IBindCtx_GetBindOptions(bctx, &bindopts);
323 ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08lx\n", hres);
324 ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
325 "bindopts.grfFlags = %08lx, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
326 ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
327 "bindopts.grfMode = %08lx, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
328 bindopts.grfMode);
329 ok(bindopts.dwTickCountDeadline == 0,
330 "bindopts.dwTickCountDeadline = %08lx, expected: 0\n", bindopts.dwTickCountDeadline);
332 IBindCtx_Release(bctx);
335 CreateBindCtx(0, &bctx_arg);
336 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
337 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08lx\n", hres);
339 if(SUCCEEDED(hres)) {
340 bindopts.cbStruct = sizeof(bindopts);
341 hres = IBindCtx_GetBindOptions(bctx, &bindopts);
342 ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08lx\n", hres);
343 ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
344 "bindopts.grfFlags = %08lx, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
345 ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
346 "bindopts.grfMode = %08lx, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
347 bindopts.grfMode);
348 ok(bindopts.dwTickCountDeadline == 0,
349 "bindopts.dwTickCountDeadline = %08lx, expected: 0\n", bindopts.dwTickCountDeadline);
351 IBindCtx_Release(bctx);
354 IBindCtx_Release(bctx_arg);
356 hres = CreateAsyncBindCtxEx(NULL, 0, bsc, NULL, &bctx, 0);
357 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08lx\n", hres);
359 if(SUCCEEDED(hres))
360 IBindCtx_Release(bctx);
362 IBindStatusCallback_Release(bsc);
365 static void test_BindToStorage(void)
367 IMoniker *mon;
368 HRESULT hres;
369 LPOLESTR display_name;
370 IBindCtx *bctx;
371 MSG msg;
372 IBindStatusCallback *previousclb, *sclb = statusclb_create();
373 IUnknown *unk = (IUnknown*)0x00ff00ff;
374 IBinding *bind;
376 hres = CreateAsyncBindCtx(0, sclb, NULL, &bctx);
377 ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08lx\n\n", hres);
378 if(FAILED(hres)) {
379 IBindStatusCallback_Release(sclb);
380 return;
383 hres = RegisterBindStatusCallback(bctx, sclb, &previousclb, 0);
384 ok(SUCCEEDED(hres), "RegisterBindStatusCallback failed: %08lx\n", hres);
385 ok(previousclb == sclb, "previousclb(%p) != sclb(%p)\n", previousclb, sclb);
386 if(previousclb)
387 IBindStatusCallback_Release(previousclb);
389 hres = CreateURLMoniker(NULL, WINE_ABOUT_URL, &mon);
390 ok(SUCCEEDED(hres), "failed to create moniker: %08lx\n", hres);
391 if(FAILED(hres)) {
392 IBindStatusCallback_Release(sclb);
393 IBindCtx_Release(bctx);
394 return;
397 hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
398 ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
399 if(SUCCEEDED(hres))
400 IBinding_Release(bind);
402 hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name);
403 ok(SUCCEEDED(hres), "GetDisplayName failed %08lx\n", hres);
404 ok(!lstrcmpW(display_name, WINE_ABOUT_URL), "GetDisplayName got wrong name\n");
406 SET_EXPECT(GetBindInfo);
407 SET_EXPECT(OnStartBinding);
408 SET_EXPECT(OnProgress_FINDINGRESOURCE);
409 SET_EXPECT(OnProgress_CONNECTING);
410 SET_EXPECT(OnProgress_SENDINGREQUEST);
411 SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
412 SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
413 SET_EXPECT(OnDataAvailable);
414 SET_EXPECT(OnProgress_DOWNLOADINGDATA);
415 SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
416 SET_EXPECT(OnStopBinding);
418 hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
419 ok(SUCCEEDED(hres), "IMoniker_BindToStorage failed: %08lx\n", hres);
420 todo_wine {
421 ok(unk == NULL, "istr should be NULL\n");
423 if(FAILED(hres)) {
424 IBindStatusCallback_Release(sclb);
425 IMoniker_Release(mon);
426 return;
428 if(unk)
429 IUnknown_Release(unk);
431 while(!stopped_binding && GetMessage(&msg,NULL,0,0)) {
432 TranslateMessage(&msg);
433 DispatchMessage(&msg);
436 CHECK_CALLED(GetBindInfo);
437 CHECK_CALLED(OnStartBinding);
438 CHECK_CALLED(OnProgress_FINDINGRESOURCE);
439 CHECK_CALLED(OnProgress_CONNECTING);
440 CHECK_CALLED(OnProgress_SENDINGREQUEST);
441 todo_wine { CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE); }
442 CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
443 CHECK_CALLED(OnDataAvailable);
444 CHECK_CALLED(OnProgress_DOWNLOADINGDATA);
445 CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
446 CHECK_CALLED(OnStopBinding);
448 ok(IMoniker_Release(mon) == 0, "mon should be destroyed here\n");
449 ok(IBindCtx_Release(bctx) == 0, "bctx should be destroyed here\n");
450 ok(IBindStatusCallback_Release(sclb) == 0, "scbl should be destroyed here\n");
453 START_TEST(url)
455 test_create();
456 test_CreateAsyncBindCtx();
457 test_CreateAsyncBindCtxEx();
458 test_BindToStorage();