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
30 #include "wine/test.h"
32 #ifdef NONAMELESSUNION
38 static const WCHAR TEST_URL_1
[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/','\0'};
39 static const WCHAR TEST_PART_URL_1
[] = {'/','t','e','s','t','/','\0'};
41 static const WCHAR WINE_ABOUT_URL
[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
42 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0};
43 static BOOL stopped_binding
= FALSE
;
45 static void test_CreateURLMoniker(LPCWSTR url1
, LPCWSTR url2
)
48 IMoniker
*mon1
= NULL
;
49 IMoniker
*mon2
= NULL
;
51 hr
= CreateURLMoniker(NULL
, url1
, &mon1
);
52 ok(SUCCEEDED(hr
), "failed to create moniker: 0x%08lx\n", hr
);
54 hr
= CreateURLMoniker(mon1
, url2
, &mon2
);
55 ok(SUCCEEDED(hr
), "failed to create moniker: 0x%08lx\n", hr
);
57 if(mon1
) IMoniker_Release(mon1
);
58 if(mon2
) IMoniker_Release(mon2
);
61 static void test_create()
63 test_CreateURLMoniker(TEST_URL_1
, TEST_PART_URL_1
);
67 IBindStatusCallbackVtbl
*lpVtbl
;
73 static HRESULT WINAPI
statusclb_QueryInterface(IBindStatusCallback
*iface
, REFIID riid
, void **ppvObject
)
78 static ULONG WINAPI
statusclb_AddRef(IBindStatusCallback
*iface
)
80 return InterlockedIncrement(&((statusclb
*)iface
)->ref
);
83 static ULONG WINAPI
statusclb_Release(IBindStatusCallback
*iface
)
85 statusclb
*This
= (statusclb
*)iface
;
87 ref
= InterlockedDecrement(&This
->ref
);
89 HeapFree(GetProcessHeap(), 0, This
);
93 static HRESULT WINAPI
statusclb_OnStartBinding(IBindStatusCallback
*iface
, DWORD dwReserved
, IBinding
*pib
)
95 statusclb
*This
= (statusclb
*)iface
;
100 ok(pib
!= NULL
, "pib should not be NULL\n");
102 IBinding_AddRef(pib
);
104 hres
= IBinding_QueryInterface(pib
, &IID_IMoniker
, (void**)&mon
);
105 ok(hres
== E_NOINTERFACE
, "IBinding should not have IMoniker interface\n");
107 IMoniker_Release(mon
);
112 static HRESULT WINAPI
statusclb_GetPriority(IBindStatusCallback
*iface
, LONG
*pnPriority
)
117 static HRESULT WINAPI
statusclb_OnLowResource(IBindStatusCallback
*iface
, DWORD reserved
)
122 static HRESULT WINAPI
statusclb_OnProgress(IBindStatusCallback
*iface
, ULONG ulProgress
, ULONG ulProgressMax
,
123 ULONG ulStatusCode
, LPCWSTR szStatusText
)
128 static HRESULT WINAPI
statusclb_OnStopBinding(IBindStatusCallback
*iface
, HRESULT hresult
, LPCWSTR szError
)
130 statusclb
*This
= (statusclb
*)iface
;
132 ok(SUCCEEDED(hresult
), "Download failed: %08lx\n", hresult
);
133 ok(szError
== NULL
, "szError should be NULL\n");
134 stopped_binding
= TRUE
;
135 IBinding_Release(This
->pbind
);
136 ok(This
->pstr
!= NULL
, "pstr should not be NULL here\n");
138 IStream_Release(This
->pstr
);
143 static HRESULT WINAPI
statusclb_GetBindInfo(IBindStatusCallback
*iface
, DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
147 *grfBINDF
= BINDF_ASYNCHRONOUS
| BINDF_ASYNCSTORAGE
| BINDF_PULLDATA
;
148 cbSize
= pbindinfo
->cbSize
;
149 memset(pbindinfo
, 0, cbSize
);
150 pbindinfo
->cbSize
= cbSize
;
155 static HRESULT WINAPI
statusclb_OnDataAvailable(IBindStatusCallback
*iface
, DWORD grfBSCF
, DWORD dwSize
,
156 FORMATETC
* pformatetc
, STGMEDIUM
* pstgmed
)
158 statusclb
*This
= (statusclb
*)iface
;
163 ok(grfBSCF
& BSCF_FIRSTDATANOTIFICATION
, "pstr should be set when BSCF_FIRSTDATANOTIFICATION\n");
164 This
->pstr
= U(*pstgmed
).pstm
;
165 IStream_AddRef(This
->pstr
);
166 ok(This
->pstr
!= NULL
, "pstr should not be NULL here\n");
169 do hres
= IStream_Read(This
->pstr
, buf
, 512, &readed
);
171 ok(hres
== S_FALSE
|| hres
== E_PENDING
, "IStream_Read returned %08lx\n", hres
);
176 static HRESULT WINAPI
statusclb_OnObjectAvailable(IBindStatusCallback
*iface
, REFIID riid
, IUnknown
*punk
)
181 static IBindStatusCallbackVtbl statusclbVtbl
= {
182 statusclb_QueryInterface
,
185 statusclb_OnStartBinding
,
186 statusclb_GetPriority
,
187 statusclb_OnLowResource
,
188 statusclb_OnProgress
,
189 statusclb_OnStopBinding
,
190 statusclb_GetBindInfo
,
191 statusclb_OnDataAvailable
,
192 statusclb_OnObjectAvailable
195 static IBindStatusCallback
* statusclb_create()
197 statusclb
*ret
= HeapAlloc(GetProcessHeap(), 0, sizeof(statusclb
));
198 ret
->lpVtbl
= &statusclbVtbl
;
202 return (IBindStatusCallback
*)ret
;
205 static void test_CreateAsyncBindCtx()
207 IBindCtx
*bctx
= (IBindCtx
*)0x0ff00ff0;
211 IBindStatusCallback
*bsc
= statusclb_create();
213 hres
= CreateAsyncBindCtx(0, NULL
, NULL
, &bctx
);
214 ok(hres
== E_INVALIDARG
, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08lx\n", hres
);
215 ok(bctx
== (IBindCtx
*)0x0ff00ff0, "bctx should not be changed\n");
217 hres
= CreateAsyncBindCtx(0, NULL
, NULL
, NULL
);
218 ok(hres
== E_INVALIDARG
, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08lx\n", hres
);
220 hres
= CreateAsyncBindCtx(0, bsc
, NULL
, &bctx
);
221 ok(SUCCEEDED(hres
), "CreateAsyncBindCtx failed: %08lx\n", hres
);
223 IBindStatusCallback_Release(bsc
);
227 bindopts
.cbStruct
= 16;
228 hres
= IBindCtx_GetBindOptions(bctx
, &bindopts
);
229 ok(SUCCEEDED(hres
), "IBindCtx_GetBindOptions failed: %08lx\n", hres
);
230 ok(bindopts
.grfFlags
== BIND_MAYBOTHERUSER
,
231 "bindopts.grfFlags = %08lx, expected: BIND_MAYBOTHERUSER\n", bindopts
.grfFlags
);
232 ok(bindopts
.grfMode
= STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
,
233 "bindopts.grfMode = %08lx, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n", bindopts
.grfMode
);
234 ok(bindopts
.dwTickCountDeadline
== 0,
235 "bindopts.dwTickCountDeadline = %08lx, expected: 0\n", bindopts
.dwTickCountDeadline
);
237 ref
= IBindCtx_Release(bctx
);
238 ok(ref
== 0, "bctx should be destroyed here\n");
239 ref
= IBindStatusCallback_Release(bsc
);
240 ok(ref
== 0, "bsc should be destroyed here\n");
243 static void test_BindToStorage()
247 LPOLESTR display_name
;
250 IBindStatusCallback
*previousclb
, *sclb
= statusclb_create();
251 IUnknown
*unk
= (IUnknown
*)0x00ff00ff;
254 hres
= CreateAsyncBindCtx(0, sclb
, NULL
, &bctx
);
255 ok(SUCCEEDED(hres
), "CreateAsyncBindCtx failed: %08lx\n\n", hres
);
257 IBindStatusCallback_Release(sclb
);
261 hres
= RegisterBindStatusCallback(bctx
, sclb
, &previousclb
, 0);
262 ok(SUCCEEDED(hres
), "RegisterBindStatusCallback failed: %08lx\n", hres
);
263 ok(previousclb
== sclb
, "previousclb(%p) != sclb(%p)\n", previousclb
, sclb
);
265 IBindStatusCallback_Release(previousclb
);
267 hres
= CreateURLMoniker(NULL
, WINE_ABOUT_URL
, &mon
);
268 ok(SUCCEEDED(hres
), "failed to create moniker: %08lx\n", hres
);
270 IBindStatusCallback_Release(sclb
);
271 IBindCtx_Release(bctx
);
275 hres
= IMoniker_QueryInterface(mon
, &IID_IBinding
, (void**)&bind
);
276 ok(hres
== E_NOINTERFACE
, "IMoniker should not have IBinding interface\n");
278 IBinding_Release(bind
);
280 hres
= IMoniker_GetDisplayName(mon
, bctx
, NULL
, &display_name
);
281 ok(SUCCEEDED(hres
), "GetDisplayName failed %08lx\n", hres
);
282 ok(!lstrcmpW(display_name
, WINE_ABOUT_URL
), "GetDisplayName got wrong name\n");
284 hres
= IMoniker_BindToStorage(mon
, bctx
, NULL
, &IID_IStream
, (void**)&unk
);
285 ok(SUCCEEDED(hres
), "IMoniker_BindToStorage failed: %08lx\n", hres
);
287 ok(unk
== NULL
, "istr should be NULL\n");
290 IBindStatusCallback_Release(sclb
);
291 IMoniker_Release(mon
);
295 IUnknown_Release(unk
);
297 while(!stopped_binding
&& GetMessage(&msg
,NULL
,0,0)) {
298 TranslateMessage(&msg
);
299 DispatchMessage(&msg
);
302 ok(IMoniker_Release(mon
) == 0, "mon should be destroyed here\n");
303 ok(IBindCtx_Release(bctx
) == 0, "bctx should be destroyed here\n");
304 ok(IBindStatusCallback_Release(sclb
) == 0, "scbl should be destroyed here\n");
310 test_CreateAsyncBindCtx();
311 test_BindToStorage();