ReactOS  0.4.15-dev-1197-g8081ba9
stream.c
Go to the documentation of this file.
1 /*
2  * Copyright 2007 Robert Shearman for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #define COBJMACROS
20 #define CONST_VTABLE
21 
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stddef.h>
25 
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "urlmon.h"
30 #include "wininet.h"
31 
32 #define DEFINE_EXPECT(func) \
33  static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
34 
35 #define SET_EXPECT(func) \
36  expect_ ## func = TRUE
37 
38 #define CHECK_EXPECT(func) \
39  do { \
40  ok(expect_ ##func, "unexpected call " #func "\n"); \
41  expect_ ## func = FALSE; \
42  called_ ## func = TRUE; \
43  }while(0)
44 
45 #define CHECK_EXPECT2(func) \
46  do { \
47  ok(expect_ ##func, "unexpected call " #func "\n"); \
48  called_ ## func = TRUE; \
49  }while(0)
50 
51 #define CHECK_CALLED(func) \
52  do { \
53  ok(called_ ## func, "expected " #func "\n"); \
54  expect_ ## func = called_ ## func = FALSE; \
55  }while(0)
56 
57 #define CHECK_NOT_CALLED(func) \
58  do { \
59  ok(!called_ ## func, "unexpected " #func "\n"); \
60  expect_ ## func = called_ ## func = FALSE; \
61  }while(0)
62 
63 #define CLEAR_CALLED(func) \
64  expect_ ## func = called_ ## func = FALSE
65 
66 DEFINE_EXPECT(QueryInterface_IServiceProvider);
67 DEFINE_EXPECT(OnStartBinding);
68 DEFINE_EXPECT(OnProgress_FINDINGRESOURCE);
69 DEFINE_EXPECT(OnProgress_CONNECTING);
70 DEFINE_EXPECT(OnProgress_SENDINGREQUEST);
71 DEFINE_EXPECT(OnProgress_MIMETYPEAVAILABLE);
72 DEFINE_EXPECT(OnProgress_BEGINDOWNLOADDATA);
73 DEFINE_EXPECT(OnProgress_DOWNLOADINGDATA);
74 DEFINE_EXPECT(OnProgress_ENDDOWNLOADDATA);
75 DEFINE_EXPECT(OnStopBinding);
76 DEFINE_EXPECT(OnDataAvailable);
77 DEFINE_EXPECT(GetBindInfo);
78 
79 static const CHAR wszIndexHtmlA[] = "index.html";
81 static const char szHtmlDoc[] = "<HTML></HTML>";
82 
84 {
85  if (IsEqualGUID(&IID_IBindStatusCallback, riid) ||
87  {
88  *ppv = iface;
89  return S_OK;
90  }
91  else if (IsEqualGUID(&IID_IServiceProvider, riid))
92  {
93  CHECK_EXPECT(QueryInterface_IServiceProvider);
94  }
95 
96  return E_NOINTERFACE;
97 }
98 
100 {
101  return 2;
102 }
103 
105 {
106  return 1;
107 }
108 
110  IBinding *pib)
111 {
112  HRESULT hres;
113  IMoniker *mon;
114 
115  CHECK_EXPECT(OnStartBinding);
116 
117  ok(pib != NULL, "pib should not be NULL\n");
118 
119  hres = IBinding_QueryInterface(pib, &IID_IMoniker, (void**)&mon);
120  ok(hres == E_NOINTERFACE, "IBinding should not have IMoniker interface\n");
121  if(SUCCEEDED(hres))
122  IMoniker_Release(mon);
123 
124  return S_OK;
125 }
126 
128 {
129  ok(0, "unexpected call\n");
130  return E_NOTIMPL;
131 }
132 
134 {
135  ok(0, "unexpected call\n");
136  return E_NOTIMPL;
137 }
138 
140  ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
141 {
142  switch(ulStatusCode) {
143  case BINDSTATUS_FINDINGRESOURCE:
144  CHECK_EXPECT(OnProgress_FINDINGRESOURCE);
145  break;
146  case BINDSTATUS_CONNECTING:
147  CHECK_EXPECT(OnProgress_CONNECTING);
148  break;
149  case BINDSTATUS_SENDINGREQUEST:
150  CHECK_EXPECT(OnProgress_SENDINGREQUEST);
151  break;
152  case BINDSTATUS_MIMETYPEAVAILABLE:
153  CHECK_EXPECT(OnProgress_MIMETYPEAVAILABLE);
154  break;
155  case BINDSTATUS_BEGINDOWNLOADDATA:
156  CHECK_EXPECT(OnProgress_BEGINDOWNLOADDATA);
157  ok(szStatusText != NULL, "szStatusText == NULL\n");
158  break;
159  case BINDSTATUS_DOWNLOADINGDATA:
160  CHECK_EXPECT2(OnProgress_DOWNLOADINGDATA);
161  break;
162  case BINDSTATUS_ENDDOWNLOADDATA:
163  CHECK_EXPECT(OnProgress_ENDDOWNLOADDATA);
164  ok(szStatusText != NULL, "szStatusText == NULL\n");
165  break;
166  case BINDSTATUS_CACHEFILENAMEAVAILABLE:
167  ok(szStatusText != NULL, "szStatusText == NULL\n");
168  break;
169  default:
170  todo_wine { ok(0, "unexpected code %d\n", ulStatusCode); }
171  };
172  return S_OK;
173 }
174 
176 {
177  CHECK_EXPECT(OnStopBinding);
178 
179  /* ignore DNS failure */
181  {
182  ok(SUCCEEDED(hresult), "Download failed: %08x\n", hresult);
183  ok(szError == NULL, "szError should be NULL\n");
184  }
185 
186  return S_OK;
187 }
188 
189 static HRESULT WINAPI statusclb_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
190 {
191  DWORD cbSize;
192 
193  CHECK_EXPECT(GetBindInfo);
194 
195  *grfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
196  cbSize = pbindinfo->cbSize;
197  memset(pbindinfo, 0, cbSize);
198  pbindinfo->cbSize = cbSize;
199 
200  return S_OK;
201 }
202 
204  DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
205 {
206  HRESULT hres;
207  DWORD readed;
208  BYTE buf[512];
209 
210  CHECK_EXPECT2(OnDataAvailable);
211 
212  if (0)
213  {
214  /* FIXME: Uncomment after removing BindToStorage hack. */
215  ok(pformatetc != NULL, "pformatetx == NULL\n");
216  if(pformatetc) {
217  ok(pformatetc->cfFormat == 0xc02d, "clipformat=%x\n", pformatetc->cfFormat);
218  ok(pformatetc->ptd == NULL, "ptd = %p\n", pformatetc->ptd);
219  ok(pformatetc->dwAspect == 1, "dwAspect=%u\n", pformatetc->dwAspect);
220  ok(pformatetc->lindex == -1, "lindex=%d\n", pformatetc->lindex);
221  ok(pformatetc->tymed == TYMED_ISTREAM, "tymed=%u\n", pformatetc->tymed);
222  }
223 
224  ok(pstgmed != NULL, "stgmeg == NULL\n");
225  if(pstgmed) {
226  ok(pstgmed->tymed == TYMED_ISTREAM, "tymed=%u\n", pstgmed->tymed);
227  ok(U(*pstgmed).pstm != NULL, "pstm == NULL\n");
228  ok(pstgmed->pUnkForRelease != NULL, "pUnkForRelease == NULL\n");
229  }
230  }
231 
232  if(U(*pstgmed).pstm) {
233  do hres = IStream_Read(U(*pstgmed).pstm, buf, 512, &readed);
234  while(hres == S_OK);
235  ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08x\n", hres);
236  }
237 
238  return S_OK;
239 }
240 
242 {
243  ok(0, "unexpected call\n");
244  return E_NOTIMPL;
245 }
246 
247 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
259 };
260 
262 
263 static void set_file_url(char *path)
264 {
265  char INDEX_HTML_A[MAX_PATH];
266 
267  lstrcpyA(INDEX_HTML_A, "file:///");
268  lstrcatA(INDEX_HTML_A, path);
269  MultiByteToWideChar(CP_ACP, 0, INDEX_HTML_A, -1, INDEX_HTML, MAX_PATH);
270 }
271 
272 static void create_file(void)
273 {
274  HANDLE file;
275  DWORD size;
276  CHAR path[MAX_PATH];
277 
280  ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
282  return;
283 
284  WriteFile(file, szHtmlDoc, sizeof(szHtmlDoc)-1, &size, NULL);
285  CloseHandle(file);
286 
288  lstrcatA(path, "\\");
291 }
292 
294 {
295  HRESULT hr;
296  IStream *pStream = NULL;
297  char buffer[256];
298 
300  ok(hr == E_INVALIDARG, "URLOpenBlockingStreamW should have failed with E_INVALIDARG instead of 0x%08x\n", hr);
301  if (0) /* crashes on Win2k */
302  {
304  ok(hr == E_INVALIDARG, "URLOpenBlockingStreamW should have failed with E_INVALIDARG instead of 0x%08x\n", hr);
305  }
306 
307  SET_EXPECT(GetBindInfo);
308  SET_EXPECT(QueryInterface_IServiceProvider);
309  SET_EXPECT(OnStartBinding);
310  SET_EXPECT(OnProgress_SENDINGREQUEST);
311  SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
312  SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
313  SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
314  SET_EXPECT(OnStopBinding);
315 
317  ok(hr == S_OK, "URLOpenBlockingStreamW failed with error 0x%08x\n", hr);
318 
319  CHECK_CALLED(GetBindInfo);
320  todo_wine CHECK_CALLED(QueryInterface_IServiceProvider);
321  CHECK_CALLED(OnStartBinding);
322  CHECK_CALLED(OnProgress_SENDINGREQUEST);
323  CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
324  CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
325  CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
326  CHECK_CALLED(OnStopBinding);
327 
328  ok(pStream != NULL, "pStream is NULL\n");
329  if(pStream)
330  {
331  buffer[0] = 0;
332  hr = IStream_Read(pStream, buffer, sizeof(buffer), NULL);
333  ok(hr == S_OK, "IStream_Read failed with error 0x%08x\n", hr);
334  ok(!memcmp(buffer, szHtmlDoc, sizeof(szHtmlDoc)-1), "read data differs from file\n");
335 
336  IStream_Release(pStream);
337  }
338 
339  hr = URLOpenBlockingStreamW(NULL, INDEX_HTML, &pStream, 0, NULL);
340  ok(hr == S_OK, "URLOpenBlockingStreamW failed with error 0x%08x\n", hr);
341 
342  ok(pStream != NULL, "pStream is NULL\n");
343  if(pStream)
344  {
345  buffer[0] = 0;
346  hr = IStream_Read(pStream, buffer, sizeof(buffer), NULL);
347  ok(hr == S_OK, "IStream_Read failed with error 0x%08x\n", hr);
348  ok(!memcmp(buffer, szHtmlDoc, sizeof(szHtmlDoc)-1), "read data differs from file\n");
349 
350  IStream_Release(pStream);
351  }
352 }
353 
354 static void test_URLOpenStreamW(void)
355 {
356  HRESULT hr;
357 
359  ok(hr == E_INVALIDARG, "URLOpenStreamW should have failed with E_INVALIDARG instead of 0x%08x\n", hr);
360 
361  SET_EXPECT(GetBindInfo);
362  SET_EXPECT(QueryInterface_IServiceProvider);
363  SET_EXPECT(OnStartBinding);
364  SET_EXPECT(OnProgress_SENDINGREQUEST);
365  SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
366  SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
367  SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
368  SET_EXPECT(OnDataAvailable);
369  SET_EXPECT(OnStopBinding);
370 
372  ok(hr == S_OK, "URLOpenStreamW failed with error 0x%08x\n", hr);
373 
374  CHECK_CALLED(GetBindInfo);
375  todo_wine CHECK_CALLED(QueryInterface_IServiceProvider);
376  CHECK_CALLED(OnStartBinding);
377  CHECK_CALLED(OnProgress_SENDINGREQUEST);
378  CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
379  CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
380  CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
381  CHECK_CALLED(OnDataAvailable);
382  CHECK_CALLED(OnStopBinding);
383 
385  ok(hr == S_OK, "URLOpenStreamW failed with error 0x%08x\n", hr);
386 }
387 
389 {
390  if(!GetProcAddress(GetModuleHandleA("urlmon.dll"), "CompareSecurityIds")) {
391  win_skip("Too old IE\n");
392  return;
393  }
394 
395  create_file();
399 }
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static const CHAR wszIndexHtmlA[]
Definition: stream.c:79
#define REFIID
Definition: guiddef.h:118
#define CloseHandle
Definition: compat.h:487
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static WCHAR INDEX_HTML[MAX_PATH]
Definition: stream.c:80
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
REFIID riid
Definition: precomp.h:44
#define CP_ACP
Definition: compat.h:109
char CHAR
Definition: xmlstorage.h:175
#define U(x)
Definition: wordpad.c:45
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define INVALID_HANDLE_VALUE
Definition: compat.h:479
GLuint buffer
Definition: glext.h:5915
#define SET_EXPECT(func)
Definition: stream.c:35
static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
Definition: stream.c:175
static ULONG WINAPI statusclb_Release(IBindStatusCallback *iface)
Definition: stream.c:104
static void test_URLOpenBlockingStreamW(void)
Definition: stream.c:293
static HRESULT WINAPI statusclb_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
Definition: stream.c:241
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
long LONG
Definition: pedump.c:60
#define GENERIC_WRITE
Definition: nt_native.h:90
r reserved
Definition: btrfs.c:2940
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
static const IBindStatusCallbackVtbl BindStatusCallbackVtbl
Definition: stream.c:247
static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
Definition: stream.c:139
static ULONG WINAPI statusclb_AddRef(IBindStatusCallback *iface)
Definition: stream.c:99
static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved, IBinding *pib)
Definition: stream.c:109
#define DEFINE_EXPECT(func)
Definition: stream.c:32
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
#define CHECK_EXPECT2(func)
Definition: stream.c:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
const GUID IID_IUnknown
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ERROR_INTERNET_NAME_NOT_RESOLVED
Definition: wininet.h:1996
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
static HRESULT WINAPI statusclb_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
Definition: stream.c:189
static void test_URLOpenStreamW(void)
Definition: stream.c:354
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
HRESULT WINAPI URLOpenStreamW(LPUNKNOWN pCaller, LPCWSTR szURL, DWORD dwReserved, LPBINDSTATUSCALLBACK lpfnCB)
Definition: umstream.c:339
#define todo_wine
Definition: test.h:162
Definition: parse.h:22
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
static void set_file_url(char *path)
Definition: stream.c:263
unsigned char BYTE
Definition: xxhash.c:193
HRESULT WINAPI URLOpenBlockingStreamW(LPUNKNOWN pCaller, LPCWSTR szURL, LPSTREAM *ppStream, DWORD dwReserved, LPBINDSTATUSCALLBACK lpfnCB)
Definition: umstream.c:290
#define S_OK
Definition: intsafe.h:51
#define CREATE_ALWAYS
Definition: disk.h:72
#define ok(value,...)
Definition: atltest.h:57
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
#define E_NOTIMPL
Definition: ddrawi.h:99
#define CHECK_CALLED(func)
Definition: stream.c:51
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
#define MultiByteToWideChar
Definition: compat.h:110
#define CHECK_EXPECT(func)
Definition: stream.c:38
unsigned int ULONG
Definition: retypes.h:1
#define GetProcAddress(x, y)
Definition: compat.h:501
static HRESULT WINAPI statusclb_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
Definition: stream.c:133
static HRESULT WINAPI statusclb_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
Definition: stream.c:83
static void create_file(void)
Definition: stream.c:272
static HRESULT WINAPI statusclb_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
Definition: stream.c:127
START_TEST(stream)
Definition: stream.c:388
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:488
#define E_PENDING
Definition: dinput.h:172
static const char szHtmlDoc[]
Definition: stream.c:81
static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
Definition: stream.c:203
#define memset(x, y, z)
Definition: compat.h:39
#define win_skip
Definition: test.h:149
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
#define SUCCEEDED(hr)
Definition: intsafe.h:49
Definition: fci.c:126