ReactOS  0.4.14-dev-554-g2f8d847
clist.c
Go to the documentation of this file.
1 /* Unit test suite for SHLWAPI Compact List and IStream ordinal functions
2  *
3  * Copyright 2002 Jon Griffiths
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #define COBJMACROS
21 #include <stdarg.h>
22 
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "objbase.h"
27 
28 typedef struct tagSHLWAPI_CLIST
29 {
33 
35 
36 /* Items to add */
38 {
39  {4, 1},
40  {8, 3},
41  {12, 2},
42  {16, 8},
43  {20, 9},
44  {3, 11},
45  {9, 82},
46  {33, 16},
47  {32, 55},
48  {24, 100},
49  {39, 116},
50  { 0, 0}
51 };
52 
53 /* Dummy IStream object for testing calls */
55 {
58  int readcalls;
66  int seekcalls;
67  int statcalls;
71 };
72 
73 static inline struct dummystream *impl_from_IStream(IStream *iface)
74 {
75  return CONTAINING_RECORD(iface, struct dummystream, IStream_iface);
76 }
77 
78 static HRESULT WINAPI QueryInterface(IStream *iface, REFIID riid, void **ret_iface)
79 {
80  if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IStream, riid)) {
81  *ret_iface = iface;
82  IStream_AddRef(iface);
83  return S_OK;
84  }
85  trace("Unexpected REFIID %s\n", wine_dbgstr_guid(riid));
86  *ret_iface = NULL;
87  return E_NOINTERFACE;
88 }
89 
90 static ULONG WINAPI AddRef(IStream *iface)
91 {
92  struct dummystream *This = impl_from_IStream(iface);
93 
94  return InterlockedIncrement(&This->ref);
95 }
96 
97 static ULONG WINAPI Release(IStream *iface)
98 {
99  struct dummystream *This = impl_from_IStream(iface);
100 
101  return InterlockedDecrement(&This->ref);
102 }
103 
104 static HRESULT WINAPI Read(IStream *iface, void *lpMem, ULONG ulSize, ULONG *lpRead)
105 {
106  struct dummystream *This = impl_from_IStream(iface);
107  HRESULT hRet = S_OK;
108 
109  ++This->readcalls;
110  if (This->failreadcall)
111  {
112  return STG_E_ACCESSDENIED;
113  }
114  else if (This->failreadsize)
115  {
116  *lpRead = ulSize + 8;
117  return S_OK;
118  }
119  else if (This->readreturnlarge)
120  {
121  *((ULONG*)lpMem) = 0xffff01;
122  *lpRead = ulSize;
123  This->readreturnlarge = FALSE;
124  return S_OK;
125  }
126  if (ulSize == sizeof(ULONG))
127  {
128  /* Read size of item */
129  *((ULONG*)lpMem) = This->item->ulSize ? This->item->ulSize + sizeof(SHLWAPI_CLIST) : 0;
130  *lpRead = ulSize;
131  }
132  else
133  {
134  unsigned int i;
135  char* buff = lpMem;
136 
137  /* Read item data */
138  if (!This->item->ulSize)
139  {
140  This->readbeyondend = TRUE;
141  *lpRead = 0;
142  return E_FAIL; /* Should never happen */
143  }
144  *((ULONG*)lpMem) = This->item->ulId;
145  *lpRead = ulSize;
146 
147  for (i = 0; i < This->item->ulSize; i++)
148  buff[4+i] = i*2;
149 
150  This->item++;
151  }
152  return hRet;
153 }
154 
155 static HRESULT WINAPI Write(IStream *iface, const void *lpMem, ULONG ulSize, ULONG *lpWritten)
156 {
157  struct dummystream *This = impl_from_IStream(iface);
158  HRESULT hRet = S_OK;
159 
160  ++This->writecalls;
161  if (This->failwritecall)
162  {
163  return STG_E_ACCESSDENIED;
164  }
165  else if (This->failwritesize)
166  {
167  *lpWritten = 0;
168  }
169  else
170  *lpWritten = ulSize;
171  return hRet;
172 }
173 
174 static HRESULT WINAPI Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin,
175  ULARGE_INTEGER *plibNewPosition)
176 {
177  struct dummystream *This = impl_from_IStream(iface);
178 
179  ++This->seekcalls;
180  This->pos.QuadPart = dlibMove.QuadPart;
181  if (plibNewPosition)
182  plibNewPosition->QuadPart = dlibMove.QuadPart;
183  return S_OK;
184 }
185 
186 static HRESULT WINAPI Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag)
187 {
188  struct dummystream *This = impl_from_IStream(iface);
189 
190  ++This->statcalls;
191  if (This->failstatcall)
192  return E_FAIL;
193  if (pstatstg)
194  pstatstg->cbSize.QuadPart = This->pos.QuadPart;
195  return S_OK;
196 }
197 
198 /* VTable */
199 static IStreamVtbl iclvt =
200 {
202  AddRef,
203  Release,
204  Read,
205  Write,
206  Seek,
207  NULL, /* SetSize */
208  NULL, /* CopyTo */
209  NULL, /* Commit */
210  NULL, /* Revert */
211  NULL, /* LockRegion */
212  NULL, /* UnlockRegion */
213  Stat,
214  NULL /* Clone */
215 };
216 
217 /* Function ptrs for ordinal calls */
219 
220 static VOID (WINAPI *pSHLWAPI_19)(LPSHLWAPI_CLIST);
221 static BOOL (WINAPI *pSHLWAPI_20)(LPSHLWAPI_CLIST*,LPCSHLWAPI_CLIST);
222 static BOOL (WINAPI *pSHLWAPI_21)(LPSHLWAPI_CLIST*,ULONG);
223 static LPSHLWAPI_CLIST (WINAPI *pSHLWAPI_22)(LPSHLWAPI_CLIST,ULONG);
224 static HRESULT (WINAPI *pSHLWAPI_17)(IStream*, SHLWAPI_CLIST*);
225 static HRESULT (WINAPI *pSHLWAPI_18)(IStream*, SHLWAPI_CLIST**);
226 
227 static BOOL (WINAPI *pSHLWAPI_166)(IStream*);
228 static HRESULT (WINAPI *pSHLWAPI_184)(IStream*, void*, ULONG);
229 static HRESULT (WINAPI *pSHLWAPI_212)(IStream*, const void*, ULONG);
230 static HRESULT (WINAPI *pSHLWAPI_213)(IStream*);
231 static HRESULT (WINAPI *pSHLWAPI_214)(IStream*, ULARGE_INTEGER*);
232 
233 
234 static BOOL InitFunctionPtrs(void)
235 {
236  SHLWAPI_hshlwapi = GetModuleHandleA("shlwapi.dll");
237 
238  /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */
239  if(!GetProcAddress(SHLWAPI_hshlwapi, "SHCreateStreamOnFileEx")){
240  win_skip("Too old shlwapi version\n");
241  return FALSE;
242  }
243 
244  pSHLWAPI_17 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)17);
245  ok(pSHLWAPI_17 != 0, "No Ordinal 17\n");
246  pSHLWAPI_18 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)18);
247  ok(pSHLWAPI_18 != 0, "No Ordinal 18\n");
248  pSHLWAPI_19 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)19);
249  ok(pSHLWAPI_19 != 0, "No Ordinal 19\n");
250  pSHLWAPI_20 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)20);
251  ok(pSHLWAPI_20 != 0, "No Ordinal 20\n");
252  pSHLWAPI_21 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)21);
253  ok(pSHLWAPI_21 != 0, "No Ordinal 21\n");
254  pSHLWAPI_22 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)22);
255  ok(pSHLWAPI_22 != 0, "No Ordinal 22\n");
256  pSHLWAPI_166 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)166);
257  ok(pSHLWAPI_166 != 0, "No Ordinal 166\n");
258  pSHLWAPI_184 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)184);
259  ok(pSHLWAPI_184 != 0, "No Ordinal 184\n");
260  pSHLWAPI_212 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)212);
261  ok(pSHLWAPI_212 != 0, "No Ordinal 212\n");
262  pSHLWAPI_213 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)213);
263  ok(pSHLWAPI_213 != 0, "No Ordinal 213\n");
264  pSHLWAPI_214 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)214);
265  ok(pSHLWAPI_214 != 0, "No Ordinal 214\n");
266 
267  return TRUE;
268 }
269 
270 static void InitDummyStream(struct dummystream *obj)
271 {
272  obj->IStream_iface.lpVtbl = &iclvt;
273  obj->ref = 1;
274  obj->readcalls = 0;
275  obj->failreadcall = FALSE;
276  obj->failreadsize = FALSE;
277  obj->readbeyondend = FALSE;
278  obj->readreturnlarge = FALSE;
279  obj->writecalls = 0;
280  obj->failwritecall = FALSE;
281  obj->failwritesize = FALSE;
282  obj->seekcalls = 0;
283  obj->statcalls = 0;
284  obj->failstatcall = FALSE;
285  obj->item = SHLWAPI_CLIST_items;
286  obj->pos.QuadPart = 0;
287 }
288 
289 
290 static void test_CList(void)
291 {
292  struct dummystream streamobj;
295  BOOL bRet;
296  HRESULT hRet;
297  LPSHLWAPI_CLIST inserted;
298  BYTE buff[64];
299  unsigned int i;
300 
301  if (!pSHLWAPI_17 || !pSHLWAPI_18 || !pSHLWAPI_19 || !pSHLWAPI_20 ||
302  !pSHLWAPI_21 || !pSHLWAPI_22)
303  return;
304 
305  /* Populate a list and test the items are added correctly */
306  while (item->ulSize)
307  {
308  /* Create item and fill with data */
309  inserted = (LPSHLWAPI_CLIST)buff;
310  inserted->ulSize = item->ulSize + sizeof(SHLWAPI_CLIST);
311  inserted->ulId = item->ulId;
312  for (i = 0; i < item->ulSize; i++)
313  buff[sizeof(SHLWAPI_CLIST)+i] = i*2;
314 
315  /* Add it */
316  bRet = pSHLWAPI_20(&list, inserted);
317  ok(bRet == TRUE, "failed list add\n");
318 
319  if (bRet == TRUE)
320  {
321  ok(list && list->ulSize, "item not added\n");
322 
323  /* Find it */
324  inserted = pSHLWAPI_22(list, item->ulId);
325  ok(inserted != NULL, "lost after adding\n");
326 
327  ok(!inserted || inserted->ulId != ~0U, "find returned a container\n");
328 
329  /* Check size */
330  if (inserted && inserted->ulSize & 0x3)
331  {
332  /* Contained */
333  ok(inserted[-1].ulId == ~0U, "invalid size is not countained\n");
334  ok(inserted[-1].ulSize > inserted->ulSize+sizeof(SHLWAPI_CLIST),
335  "container too small\n");
336  }
337  else if (inserted)
338  {
339  ok(inserted->ulSize==item->ulSize+sizeof(SHLWAPI_CLIST),
340  "id %d wrong size %d\n", inserted->ulId, inserted->ulSize);
341  }
342  if (inserted)
343  {
344  BOOL bDataOK = TRUE;
345  LPBYTE bufftest = (LPBYTE)inserted;
346 
347  for (i = 0; i < inserted->ulSize - sizeof(SHLWAPI_CLIST); i++)
348  if (bufftest[sizeof(SHLWAPI_CLIST)+i] != i*2)
349  bDataOK = FALSE;
350 
351  ok(bDataOK == TRUE, "data corrupted on insert\n");
352  }
353  ok(!inserted || inserted->ulId==item->ulId, "find got wrong item\n");
354  }
355  item++;
356  }
357 
358  /* Write the list */
359  InitDummyStream(&streamobj);
360 
361  hRet = pSHLWAPI_17(&streamobj.IStream_iface, list);
362  ok(hRet == S_OK, "write failed\n");
363  if (hRet == S_OK)
364  {
365  /* 1 call for each element, + 1 for OK (use our null element for this) */
366  ok(streamobj.writecalls == ARRAY_SIZE(SHLWAPI_CLIST_items), "wrong call count\n");
367  ok(streamobj.readcalls == 0,"called Read() in write\n");
368  ok(streamobj.seekcalls == 0,"called Seek() in write\n");
369  }
370 
371  /* Failure cases for writing */
372  InitDummyStream(&streamobj);
373  streamobj.failwritecall = TRUE;
374  hRet = pSHLWAPI_17(&streamobj.IStream_iface, list);
375  ok(hRet == STG_E_ACCESSDENIED, "changed object failure return\n");
376  ok(streamobj.writecalls == 1, "called object after failure\n");
377  ok(streamobj.readcalls == 0,"called Read() after failure\n");
378  ok(streamobj.seekcalls == 0,"called Seek() after failure\n");
379 
380  InitDummyStream(&streamobj);
381  streamobj.failwritesize = TRUE;
382  hRet = pSHLWAPI_17(&streamobj.IStream_iface, list);
383  ok(hRet == STG_E_MEDIUMFULL || broken(hRet == E_FAIL) /* Win7 */,
384  "changed size failure return\n");
385  ok(streamobj.writecalls == 1, "called object after size failure\n");
386  ok(streamobj.readcalls == 0,"called Read() after failure\n");
387  ok(streamobj.seekcalls == 0,"called Seek() after failure\n");
388 
389  /* Invalid inputs for adding */
390  inserted = (LPSHLWAPI_CLIST)buff;
391  inserted->ulSize = sizeof(SHLWAPI_CLIST) -1;
392  inserted->ulId = 33;
393  bRet = pSHLWAPI_20(&list, inserted);
394  ok(bRet == FALSE, "Expected failure\n");
395 
396  inserted = pSHLWAPI_22(list, 33);
397  ok(inserted == NULL, "inserted bad element size\n");
398 
399  inserted = (LPSHLWAPI_CLIST)buff;
400  inserted->ulSize = 44;
401  inserted->ulId = ~0U;
402  bRet = pSHLWAPI_20(&list, inserted);
403  ok(bRet == FALSE, "Expected failure\n");
404 
406 
407  /* Look for nonexistent item in populated list */
408  inserted = pSHLWAPI_22(list, 99999999);
409  ok(inserted == NULL, "found a nonexistent item\n");
410 
411  while (item->ulSize)
412  {
413  /* Delete items */
414  BOOL bRet = pSHLWAPI_21(&list, item->ulId);
415  ok(bRet == TRUE, "couldn't find item to delete\n");
416  item++;
417  }
418 
419  /* Look for nonexistent item in empty list */
420  inserted = pSHLWAPI_22(list, 99999999);
421  ok(inserted == NULL, "found an item in empty list\n");
422 
423  /* Create a list by reading in data */
424  InitDummyStream(&streamobj);
425 
426  hRet = pSHLWAPI_18(&streamobj.IStream_iface, &list);
427  ok(hRet == S_OK, "failed create from Read()\n");
428  if (hRet == S_OK)
429  {
430  ok(streamobj.readbeyondend == FALSE, "read beyond end\n");
431  /* 2 calls per item, but only 1 for the terminator */
432  ok(streamobj.readcalls == ARRAY_SIZE(SHLWAPI_CLIST_items) * 2 - 1, "wrong call count\n");
433  ok(streamobj.writecalls == 0, "called Write() from create\n");
434  ok(streamobj.seekcalls == 0,"called Seek() from create\n");
435 
437 
438  /* Check the items were added correctly */
439  while (item->ulSize)
440  {
441  inserted = pSHLWAPI_22(list, item->ulId);
442  ok(inserted != NULL, "lost after adding\n");
443 
444  ok(!inserted || inserted->ulId != ~0U, "find returned a container\n");
445 
446  /* Check size */
447  if (inserted && inserted->ulSize & 0x3)
448  {
449  /* Contained */
450  ok(inserted[-1].ulId == ~0U, "invalid size is not countained\n");
451  ok(inserted[-1].ulSize > inserted->ulSize+sizeof(SHLWAPI_CLIST),
452  "container too small\n");
453  }
454  else if (inserted)
455  {
456  ok(inserted->ulSize==item->ulSize+sizeof(SHLWAPI_CLIST),
457  "id %d wrong size %d\n", inserted->ulId, inserted->ulSize);
458  }
459  ok(!inserted || inserted->ulId==item->ulId, "find got wrong item\n");
460  if (inserted)
461  {
462  BOOL bDataOK = TRUE;
463  LPBYTE bufftest = (LPBYTE)inserted;
464 
465  for (i = 0; i < inserted->ulSize - sizeof(SHLWAPI_CLIST); i++)
466  if (bufftest[sizeof(SHLWAPI_CLIST)+i] != i*2)
467  bDataOK = FALSE;
468 
469  ok(bDataOK == TRUE, "data corrupted on insert\n");
470  }
471  item++;
472  }
473  }
474 
475  /* Failure cases for reading */
476  InitDummyStream(&streamobj);
477  streamobj.failreadcall = TRUE;
478  hRet = pSHLWAPI_18(&streamobj.IStream_iface, &list);
479  ok(hRet == STG_E_ACCESSDENIED, "changed object failure return\n");
480  ok(streamobj.readbeyondend == FALSE, "read beyond end\n");
481  ok(streamobj.readcalls == 1, "called object after read failure\n");
482  ok(streamobj.writecalls == 0,"called Write() after read failure\n");
483  ok(streamobj.seekcalls == 0,"called Seek() after read failure\n");
484 
485  /* Read returns large object */
486  InitDummyStream(&streamobj);
487  streamobj.readreturnlarge = TRUE;
488  hRet = pSHLWAPI_18(&streamobj.IStream_iface, &list);
489  ok(hRet == S_OK, "failed create from Read() with large item\n");
490  ok(streamobj.readbeyondend == FALSE, "read beyond end\n");
491  ok(streamobj.readcalls == 1,"wrong call count\n");
492  ok(streamobj.writecalls == 0,"called Write() after read failure\n");
493  ok(streamobj.seekcalls == 2,"wrong Seek() call count (%d)\n", streamobj.seekcalls);
494 
495  pSHLWAPI_19(list);
496 }
497 
498 static BOOL test_SHLWAPI_166(void)
499 {
500  struct dummystream streamobj;
501  BOOL bRet;
502 
503  if (!pSHLWAPI_166)
504  return FALSE;
505 
506  InitDummyStream(&streamobj);
507  bRet = pSHLWAPI_166(&streamobj.IStream_iface);
508 
509  if (bRet != TRUE)
510  return FALSE; /* This version doesn't support stream ops on clists */
511 
512  ok(streamobj.readcalls == 0, "called Read()\n");
513  ok(streamobj.writecalls == 0, "called Write()\n");
514  ok(streamobj.seekcalls == 0, "called Seek()\n");
515  ok(streamobj.statcalls == 1, "wrong call count\n");
516 
517  streamobj.statcalls = 0;
518  streamobj.pos.QuadPart = 50001;
519 
520  bRet = pSHLWAPI_166(&streamobj.IStream_iface);
521 
522  ok(bRet == FALSE, "failed after seek adjusted\n");
523  ok(streamobj.readcalls == 0, "called Read()\n");
524  ok(streamobj.writecalls == 0, "called Write()\n");
525  ok(streamobj.seekcalls == 0, "called Seek()\n");
526  ok(streamobj.statcalls == 1, "wrong call count\n");
527 
528  /* Failure cases */
529  InitDummyStream(&streamobj);
530  streamobj.pos.QuadPart = 50001;
531  streamobj.failstatcall = TRUE; /* 1: Stat() Bad, Read() OK */
532  bRet = pSHLWAPI_166(&streamobj.IStream_iface);
533  ok(bRet == FALSE, "should be FALSE after read is OK\n");
534  ok(streamobj.readcalls == 1, "wrong call count\n");
535  ok(streamobj.writecalls == 0, "called Write()\n");
536  ok(streamobj.seekcalls == 1, "wrong call count\n");
537  ok(streamobj.statcalls == 1, "wrong call count\n");
538  ok(streamobj.pos.QuadPart == 0, "Didn't seek to start\n");
539 
540  InitDummyStream(&streamobj);
541  streamobj.pos.QuadPart = 50001;
542  streamobj.failstatcall = TRUE;
543  streamobj.failreadcall = TRUE; /* 2: Stat() Bad, Read() Bad Also */
544  bRet = pSHLWAPI_166(&streamobj.IStream_iface);
545  ok(bRet == TRUE, "Should be true after read fails\n");
546  ok(streamobj.readcalls == 1, "wrong call count\n");
547  ok(streamobj.writecalls == 0, "called Write()\n");
548  ok(streamobj.seekcalls == 0, "Called Seek()\n");
549  ok(streamobj.statcalls == 1, "wrong call count\n");
550  ok(streamobj.pos.QuadPart == 50001, "called Seek() after read failed\n");
551  return TRUE;
552 }
553 
554 static void test_SHLWAPI_184(void)
555 {
556  struct dummystream streamobj;
557  char buff[256];
558  HRESULT hRet;
559 
560  if (!pSHLWAPI_184)
561  return;
562 
563  InitDummyStream(&streamobj);
564  hRet = pSHLWAPI_184(&streamobj.IStream_iface, buff, sizeof(buff));
565 
566  ok(hRet == S_OK, "failed Read()\n");
567  ok(streamobj.readcalls == 1, "wrong call count\n");
568  ok(streamobj.writecalls == 0, "called Write()\n");
569  ok(streamobj.seekcalls == 0, "called Seek()\n");
570 }
571 
572 static void test_SHLWAPI_212(void)
573 {
574  struct dummystream streamobj;
575  char buff[256];
576  HRESULT hRet;
577 
578  if (!pSHLWAPI_212)
579  return;
580 
581  InitDummyStream(&streamobj);
582  hRet = pSHLWAPI_212(&streamobj.IStream_iface, buff, sizeof(buff));
583 
584  ok(hRet == S_OK, "failed Write()\n");
585  ok(streamobj.readcalls == 0, "called Read()\n");
586  ok(streamobj.writecalls == 1, "wrong call count\n");
587  ok(streamobj.seekcalls == 0, "called Seek()\n");
588 }
589 
590 static void test_SHLWAPI_213(void)
591 {
592  struct dummystream streamobj;
593  ULARGE_INTEGER ul;
595  HRESULT hRet;
596 
597  if (!pSHLWAPI_213 || !pSHLWAPI_214)
598  return;
599 
600  InitDummyStream(&streamobj);
601  ll.QuadPart = 5000l;
602  Seek(&streamobj.IStream_iface, ll, 0, NULL); /* Seek to 5000l */
603 
604  streamobj.seekcalls = 0;
605  pSHLWAPI_213(&streamobj.IStream_iface); /* Should rewind */
606  ok(streamobj.statcalls == 0, "called Stat()\n");
607  ok(streamobj.readcalls == 0, "called Read()\n");
608  ok(streamobj.writecalls == 0, "called Write()\n");
609  ok(streamobj.seekcalls == 1, "wrong call count\n");
610 
611  ul.QuadPart = 50001;
612  hRet = pSHLWAPI_214(&streamobj.IStream_iface, &ul);
613  ok(hRet == S_OK, "failed Stat()\n");
614  ok(ul.QuadPart == 0, "213 didn't rewind stream\n");
615 }
616 
617 static void test_SHLWAPI_214(void)
618 {
619  struct dummystream streamobj;
620  ULARGE_INTEGER ul;
622  HRESULT hRet;
623 
624  if (!pSHLWAPI_214)
625  return;
626 
627  InitDummyStream(&streamobj);
628  ll.QuadPart = 5000l;
629  Seek(&streamobj.IStream_iface, ll, 0, NULL);
630  ul.QuadPart = 0;
631  streamobj.seekcalls = 0;
632  hRet = pSHLWAPI_214(&streamobj.IStream_iface, &ul);
633 
634  ok(hRet == S_OK, "failed Stat()\n");
635  ok(streamobj.statcalls == 1, "wrong call count\n");
636  ok(streamobj.readcalls == 0, "called Read()\n");
637  ok(streamobj.writecalls == 0, "called Write()\n");
638  ok(streamobj.seekcalls == 0, "called Seek()\n");
639  ok(ul.QuadPart == 5000l, "Stat gave wrong size\n");
640 }
641 
643 {
644  if(!InitFunctionPtrs())
645  return;
646 
647  test_CList();
648 
649  /* Test streaming if this version supports it */
650  if (test_SHLWAPI_166())
651  {
656  }
657 }
struct tagSHLWAPI_CLIST * LPSHLWAPI_CLIST
static void test_SHLWAPI_212(void)
Definition: clist.c:572
static VOID(WINAPI *pSHLWAPI_19)(LPSHLWAPI_CLIST)
static HRESULT WINAPI QueryInterface(IStream *iface, REFIID riid, void **ret_iface)
Definition: clist.c:78
START_TEST(clist)
Definition: clist.c:642
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define E_NOINTERFACE
Definition: winerror.h:2364
int seekcalls
Definition: clist.c:66
BOOL failreadsize
Definition: clist.c:60
LONG ref
Definition: clist.c:57
REFIID riid
Definition: precomp.h:44
static IStreamVtbl iclvt
Definition: clist.c:199
#define U(x)
Definition: wordpad.c:44
static ULONG
Definition: clist.c:222
ULARGE_INTEGER pos
Definition: clist.c:70
static void test_SHLWAPI_184(void)
Definition: clist.c:554
const char * wine_dbgstr_guid(const GUID *guid)
#define STG_E_MEDIUMFULL
Definition: winerror.h:2581
BOOL failreadcall
Definition: clist.c:59
static void test_CList(void)
Definition: clist.c:290
char * LPSTR
Definition: xmlstorage.h:182
#define E_FAIL
Definition: ddrawi.h:102
int writecalls
Definition: clist.c:63
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned char * LPBYTE
Definition: typedefs.h:52
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define STG_E_ACCESSDENIED
Definition: winerror.h:2568
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
BOOL failstatcall
Definition: clist.c:68
static HRESULT(WINAPI *pSHLWAPI_17)(IStream *
smooth NULL
Definition: ftsmooth.c:416
ULONG ulId
Definition: clist.c:31
BOOL readreturnlarge
Definition: clist.c:62
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
BOOL readbeyondend
Definition: clist.c:61
r l[0]
Definition: byte_order.h:167
static void test_SHLWAPI_214(void)
Definition: clist.c:617
static void InitDummyStream(struct dummystream *obj)
Definition: clist.c:270
#define trace
Definition: atltest.h:70
static BOOL(WINAPI *pSHLWAPI_20)(LPSHLWAPI_CLIST *
struct tagSHLWAPI_CLIST SHLWAPI_CLIST
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
static ULARGE_INTEGER *static BOOL InitFunctionPtrs(void)
Definition: clist.c:234
static const SHLWAPI_CLIST SHLWAPI_CLIST_items[]
Definition: clist.c:37
#define InterlockedDecrement
Definition: armddk.h:52
int statcalls
Definition: clist.c:67
unsigned char BYTE
Definition: mem.h:68
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
static HRESULT WINAPI Write(IStream *iface, const void *lpMem, ULONG ulSize, ULONG *lpWritten)
Definition: clist.c:155
Definition: _list.h:228
#define broken(x)
Definition: _sntprintf.h:21
static ULONG WINAPI Release(IStream *iface)
Definition: clist.c:97
static HRESULT WINAPI Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: clist.c:174
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
static ATOM item
Definition: dde.c:856
static void test_SHLWAPI_213(void)
Definition: clist.c:590
#define ARRAY_SIZE(a)
Definition: main.h:24
#define ok(value,...)
Definition: atltest.h:57
w ll
Definition: byte_order.h:166
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
static struct dummystream * impl_from_IStream(IStream *iface)
Definition: clist.c:73
static HMODULE SHLWAPI_hshlwapi
Definition: clist.c:218
int readcalls
Definition: clist.c:58
BOOL failwritesize
Definition: clist.c:65
BOOL failwritecall
Definition: clist.c:64
static BOOL test_SHLWAPI_166(void)
Definition: clist.c:498
unsigned int ULONG
Definition: retypes.h:1
LPCSHLWAPI_CLIST item
Definition: clist.c:69
#define GetProcAddress(x, y)
Definition: compat.h:418
static HRESULT WINAPI Read(IStream *iface, void *lpMem, ULONG ulSize, ULONG *lpRead)
Definition: clist.c:104
IStream IStream_iface
Definition: clist.c:56
#define win_skip
Definition: test.h:150
const SHLWAPI_CLIST * LPCSHLWAPI_CLIST
Definition: clist.c:34
static unsigned char buff[32768]
Definition: fatten.c:17
static HRESULT WINAPI Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag)
Definition: clist.c:186
ULONG ulSize
Definition: clist.c:30
LONGLONG QuadPart
Definition: typedefs.h:112