ReactOS 0.4.16-dev-1946-g52006dd
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#include "shlobj.h"
28
29/* Items to add */
31{
32 {4, 1},
33 {8, 3},
34 {12, 2},
35 {16, 8},
36 {20, 9},
37 {3, 11},
38 {9, 82},
39 {33, 16},
40 {32, 55},
41 {24, 100},
42 {39, 116},
43 { 0, 0}
44};
45
46/* Dummy IStream object for testing calls */
48{
64};
65
66static inline struct dummystream *impl_from_IStream(IStream *iface)
67{
68 return CONTAINING_RECORD(iface, struct dummystream, IStream_iface);
69}
70
71static HRESULT WINAPI QueryInterface(IStream *iface, REFIID riid, void **ret_iface)
72{
73 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IStream, riid)) {
74 *ret_iface = iface;
75 IStream_AddRef(iface);
76 return S_OK;
77 }
78 trace("Unexpected REFIID %s\n", wine_dbgstr_guid(riid));
79 *ret_iface = NULL;
80 return E_NOINTERFACE;
81}
82
83static ULONG WINAPI AddRef(IStream *iface)
84{
85 struct dummystream *This = impl_from_IStream(iface);
86
87 return InterlockedIncrement(&This->ref);
88}
89
91{
92 struct dummystream *This = impl_from_IStream(iface);
93
94 return InterlockedDecrement(&This->ref);
95}
96
97static HRESULT WINAPI Read(IStream *iface, void *lpMem, ULONG ulSize, ULONG *lpRead)
98{
99 struct dummystream *This = impl_from_IStream(iface);
100 HRESULT hRet = S_OK;
101
102 ++This->readcalls;
103 if (This->failreadcall)
104 {
105 return STG_E_ACCESSDENIED;
106 }
107 else if (This->failreadsize)
108 {
109 *lpRead = ulSize + 8;
110 return S_OK;
111 }
112 else if (This->readreturnlarge)
113 {
114 *((ULONG*)lpMem) = 0xffff01;
115 *lpRead = ulSize;
116 This->readreturnlarge = FALSE;
117 return S_OK;
118 }
119 if (ulSize == sizeof(ULONG))
120 {
121 /* Read size of item */
122 *((ULONG*)lpMem) = This->item->cbSize ? This->item->cbSize + sizeof(DATABLOCK_HEADER) : 0;
123 *lpRead = ulSize;
124 }
125 else
126 {
127 unsigned int i;
128 char* buff = lpMem;
129
130 /* Read item data */
131 if (!This->item->cbSize)
132 {
133 This->readbeyondend = TRUE;
134 *lpRead = 0;
135 return E_FAIL; /* Should never happen */
136 }
137 *((ULONG *)lpMem) = This->item->dwSignature;
138 *lpRead = ulSize;
139
140 for (i = 0; i < This->item->cbSize; i++)
141 buff[4+i] = i*2;
142
143 This->item++;
144 }
145 return hRet;
146}
147
148static HRESULT WINAPI Write(IStream *iface, const void *lpMem, ULONG ulSize, ULONG *lpWritten)
149{
150 struct dummystream *This = impl_from_IStream(iface);
151 HRESULT hRet = S_OK;
152
153 ++This->writecalls;
154 if (This->failwritecall)
155 {
156 return STG_E_ACCESSDENIED;
157 }
158 else if (This->failwritesize)
159 {
160 *lpWritten = 0;
161 }
162 else
163 *lpWritten = ulSize;
164 return hRet;
165}
166
167static HRESULT WINAPI Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin,
168 ULARGE_INTEGER *plibNewPosition)
169{
170 struct dummystream *This = impl_from_IStream(iface);
171
172 ++This->seekcalls;
173 This->pos.QuadPart = dlibMove.QuadPart;
174 if (plibNewPosition)
175 plibNewPosition->QuadPart = dlibMove.QuadPart;
176 return S_OK;
177}
178
179static HRESULT WINAPI Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag)
180{
181 struct dummystream *This = impl_from_IStream(iface);
182
183 ++This->statcalls;
184 if (This->failstatcall)
185 return E_FAIL;
186 if (pstatstg)
187 pstatstg->cbSize.QuadPart = This->pos.QuadPart;
188 return S_OK;
189}
190
191/* VTable */
192static IStreamVtbl iclvt =
193{
195 AddRef,
196 Release,
197 Read,
198 Write,
199 Seek,
200 NULL, /* SetSize */
201 NULL, /* CopyTo */
202 NULL, /* Commit */
203 NULL, /* Revert */
204 NULL, /* LockRegion */
205 NULL, /* UnlockRegion */
206 Stat,
207 NULL /* Clone */
208};
209
210/* Function ptrs for ordinal calls */
212
213static void (WINAPI *pSHFreeDataBlockList)(DATABLOCK_HEADER *);
214static HRESULT (WINAPI *pSHAddDataBlock)(DATABLOCK_HEADER **, DATABLOCK_HEADER *);
215static BOOL (WINAPI *pSHRemoveDataBlock)(DATABLOCK_HEADER **,ULONG);
217static HRESULT (WINAPI *pSHWriteDataBlockList)(IStream *, DATABLOCK_HEADER *);
218static HRESULT (WINAPI *pSHReadDataBlockList)(IStream *, DATABLOCK_HEADER **);
219
220static BOOL (WINAPI *pSHIsEmptyStream)(IStream *);
221static HRESULT (WINAPI *pIStream_Read)(IStream *, void *, ULONG);
222static HRESULT (WINAPI *pIStream_Write)(IStream *, const void *, ULONG);
223static HRESULT (WINAPI *pIStream_Reset)(IStream *);
224static HRESULT (WINAPI *pIStream_Size)(IStream *, ULARGE_INTEGER *);
225
226
228{
229 SHLWAPI_hshlwapi = GetModuleHandleA("shlwapi.dll");
230
231 /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */
232 if(!GetProcAddress(SHLWAPI_hshlwapi, "SHCreateStreamOnFileEx")){
233 win_skip("Too old shlwapi version\n");
234 return FALSE;
235 }
236
237 pSHWriteDataBlockList = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)17);
238 ok(pSHWriteDataBlockList != 0, "No Ordinal 17\n");
239 pSHReadDataBlockList = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)18);
240 ok(pSHReadDataBlockList != 0, "No Ordinal 18\n");
241 pSHFreeDataBlockList = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)19);
242 ok(pSHFreeDataBlockList != 0, "No Ordinal 19\n");
243 pSHAddDataBlock = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)20);
244 ok(pSHAddDataBlock != 0, "No Ordinal 20\n");
245 pSHRemoveDataBlock = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)21);
246 ok(pSHRemoveDataBlock != 0, "No Ordinal 21\n");
248 ok(pSHFindDataBlock != 0, "No Ordinal 22\n");
249 pSHIsEmptyStream = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)166);
250 ok(pSHIsEmptyStream != 0, "No Ordinal 166\n");
251 pIStream_Read = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)184);
252 ok(pIStream_Read != 0, "No Ordinal 184\n");
253 pIStream_Write = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)212);
254 ok(pIStream_Write != 0, "No Ordinal 212\n");
255 pIStream_Reset = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)213);
256 ok(pIStream_Reset != 0, "No Ordinal 213\n");
257 pIStream_Size = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)214);
258 ok(pIStream_Size != 0, "No Ordinal 214\n");
259
260 return TRUE;
261}
262
263static void InitDummyStream(struct dummystream *obj)
264{
265 obj->IStream_iface.lpVtbl = &iclvt;
266 obj->ref = 1;
267 obj->readcalls = 0;
268 obj->failreadcall = FALSE;
269 obj->failreadsize = FALSE;
270 obj->readbeyondend = FALSE;
271 obj->readreturnlarge = FALSE;
272 obj->writecalls = 0;
273 obj->failwritecall = FALSE;
274 obj->failwritesize = FALSE;
275 obj->seekcalls = 0;
276 obj->statcalls = 0;
277 obj->failstatcall = FALSE;
278 obj->item = clist_items;
279 obj->pos.QuadPart = 0;
280}
281
282
283static void test_CList(void)
284{
285 struct dummystream streamobj;
288 HRESULT hRet;
289 DATABLOCK_HEADER *inserted;
290 BYTE buff[64];
291 unsigned int i;
292 BOOL ret;
293
294 if (!pSHWriteDataBlockList || !pSHReadDataBlockList || !pSHFreeDataBlockList || !pSHAddDataBlock ||
295 !pSHRemoveDataBlock || !pSHFindDataBlock)
296 return;
297
298 /* Populate a list and test the items are added correctly */
299 while (item->cbSize)
300 {
301 /* Create item and fill with data */
302 inserted = (DATABLOCK_HEADER *)buff;
303 inserted->cbSize = item->cbSize + sizeof(DATABLOCK_HEADER);
304 inserted->dwSignature = item->dwSignature;
305 for (i = 0; i < item->cbSize; i++)
306 buff[sizeof(DATABLOCK_HEADER) + i] = i * 2;
307
308 ret = pSHAddDataBlock(&list, inserted);
309 ok(ret == TRUE, "got %d\n", ret);
310
311 if (ret == TRUE)
312 {
313 ok(list && list->cbSize, "item not added\n");
314
315 inserted = pSHFindDataBlock(list, item->dwSignature);
316 ok(inserted != NULL, "lost after adding\n");
317
318 ok(!inserted || inserted->dwSignature != ~0U, "find returned a container\n");
319
320 /* Check size */
321 if (inserted && (inserted->cbSize & 0x3))
322 {
323 /* Contained */
324 ok(inserted[-1].dwSignature == ~0U, "invalid size is not countained\n");
325 ok(inserted[-1].cbSize > inserted->cbSize + sizeof(DATABLOCK_HEADER),
326 "container too small\n");
327 }
328 else if (inserted)
329 {
330 ok(inserted->cbSize == item->cbSize + sizeof(DATABLOCK_HEADER),
331 "id %ld wrong size %ld\n", inserted->dwSignature, inserted->cbSize);
332 }
333 if (inserted)
334 {
335 BOOL bDataOK = TRUE;
336 LPBYTE bufftest = (LPBYTE)inserted;
337
338 for (i = 0; i < inserted->cbSize - sizeof(DATABLOCK_HEADER); i++)
339 if (bufftest[sizeof(DATABLOCK_HEADER) + i] != i * 2)
340 bDataOK = FALSE;
341
342 ok(bDataOK == TRUE, "data corrupted on insert\n");
343 }
344 ok(!inserted || inserted->dwSignature == item->dwSignature, "find got wrong item\n");
345 }
346 item++;
347 }
348
349 /* Write the list */
350 InitDummyStream(&streamobj);
351
352 hRet = pSHWriteDataBlockList(&streamobj.IStream_iface, list);
353 ok(hRet == S_OK, "write failed\n");
354 if (hRet == S_OK)
355 {
356 /* 1 call for each element, + 1 for OK (use our null element for this) */
357 ok(streamobj.writecalls == ARRAY_SIZE(clist_items), "wrong call count\n");
358 ok(streamobj.readcalls == 0,"called Read() in write\n");
359 ok(streamobj.seekcalls == 0,"called Seek() in write\n");
360 }
361
362 /* Failure cases for writing */
363 InitDummyStream(&streamobj);
364 streamobj.failwritecall = TRUE;
365 hRet = pSHWriteDataBlockList(&streamobj.IStream_iface, list);
366 ok(hRet == STG_E_ACCESSDENIED, "changed object failure return\n");
367 ok(streamobj.writecalls == 1, "called object after failure\n");
368 ok(streamobj.readcalls == 0,"called Read() after failure\n");
369 ok(streamobj.seekcalls == 0,"called Seek() after failure\n");
370
371 InitDummyStream(&streamobj);
372 streamobj.failwritesize = TRUE;
373 hRet = pSHWriteDataBlockList(&streamobj.IStream_iface, list);
374 ok(hRet == STG_E_MEDIUMFULL || broken(hRet == E_FAIL) /* Win7 */,
375 "changed size failure return\n");
376 ok(streamobj.writecalls == 1, "called object after size failure\n");
377 ok(streamobj.readcalls == 0,"called Read() after failure\n");
378 ok(streamobj.seekcalls == 0,"called Seek() after failure\n");
379
380 /* Invalid inputs for adding */
381 inserted = (DATABLOCK_HEADER *)buff;
382 inserted->cbSize = sizeof(DATABLOCK_HEADER) - 1;
383 inserted->dwSignature = 33;
384
385 ret = pSHAddDataBlock(NULL, inserted);
386 ok(!ret, "got %d\n", ret);
387
388 ret = pSHAddDataBlock(&list, inserted);
389 ok(!ret, "got %d\n", ret);
390
391 inserted = pSHFindDataBlock(list, 33);
392 ok(inserted == NULL, "inserted bad element size\n");
393
394 inserted = (DATABLOCK_HEADER *)buff;
395 inserted->cbSize = 44;
396 inserted->dwSignature = ~0U;
397
398 ret = pSHAddDataBlock(&list, inserted);
399 ok(!ret, "got %d\n", ret);
400
402
403 /* Look for nonexistent item in populated list */
404 inserted = pSHFindDataBlock(list, 99999999);
405 ok(inserted == NULL, "found a nonexistent item\n");
406
407 while (item->cbSize)
408 {
409 BOOL bRet = pSHRemoveDataBlock(&list, item->dwSignature);
410 ok(bRet == TRUE, "couldn't find item to delete\n");
411 item++;
412 }
413
414 /* Look for nonexistent item in empty list */
415 inserted = pSHFindDataBlock(list, 99999999);
416 ok(inserted == NULL, "found an item in empty list\n");
417
418 /* Create a list by reading in data */
419 InitDummyStream(&streamobj);
420
421 hRet = pSHReadDataBlockList(&streamobj.IStream_iface, &list);
422 ok(hRet == S_OK, "failed create from Read()\n");
423 if (hRet == S_OK)
424 {
425 ok(streamobj.readbeyondend == FALSE, "read beyond end\n");
426 /* 2 calls per item, but only 1 for the terminator */
427 ok(streamobj.readcalls == ARRAY_SIZE(clist_items) * 2 - 1, "wrong call count\n");
428 ok(streamobj.writecalls == 0, "called Write() from create\n");
429 ok(streamobj.seekcalls == 0,"called Seek() from create\n");
430
432
433 /* Check the items were added correctly */
434 while (item->cbSize)
435 {
436 inserted = pSHFindDataBlock(list, item->dwSignature);
437 ok(inserted != NULL, "lost after adding\n");
438
439 ok(!inserted || inserted->dwSignature != ~0U, "find returned a container\n");
440
441 /* Check size */
442 if (inserted && inserted->cbSize & 0x3)
443 {
444 /* Contained */
445 ok(inserted[-1].dwSignature == ~0U, "invalid size is not countained\n");
446 ok(inserted[-1].cbSize > inserted->cbSize + sizeof(DATABLOCK_HEADER),
447 "container too small\n");
448 }
449 else if (inserted)
450 {
451 ok(inserted->cbSize == item->cbSize + sizeof(DATABLOCK_HEADER),
452 "id %ld wrong size %ld\n", inserted->dwSignature, inserted->cbSize);
453 }
454 ok(!inserted || inserted->dwSignature == item->dwSignature, "find got wrong item\n");
455 if (inserted)
456 {
457 BOOL bDataOK = TRUE;
458 LPBYTE bufftest = (LPBYTE)inserted;
459
460 for (i = 0; i < inserted->cbSize - sizeof(DATABLOCK_HEADER); i++)
461 if (bufftest[sizeof(DATABLOCK_HEADER) + i] != i * 2)
462 bDataOK = FALSE;
463
464 ok(bDataOK == TRUE, "data corrupted on insert\n");
465 }
466 item++;
467 }
468 }
469
470 /* Failure cases for reading */
471 InitDummyStream(&streamobj);
472 streamobj.failreadcall = TRUE;
473 hRet = pSHReadDataBlockList(&streamobj.IStream_iface, &list);
474 ok(hRet == STG_E_ACCESSDENIED, "changed object failure return\n");
475 ok(streamobj.readbeyondend == FALSE, "read beyond end\n");
476 ok(streamobj.readcalls == 1, "called object after read failure\n");
477 ok(streamobj.writecalls == 0,"called Write() after read failure\n");
478 ok(streamobj.seekcalls == 0,"called Seek() after read failure\n");
479
480 /* Read returns large object */
481 InitDummyStream(&streamobj);
482 streamobj.readreturnlarge = TRUE;
483 hRet = pSHReadDataBlockList(&streamobj.IStream_iface, &list);
484 ok(hRet == S_OK, "failed create from Read() with large item\n");
485 ok(streamobj.readbeyondend == FALSE, "read beyond end\n");
486 ok(streamobj.readcalls == 1,"wrong call count\n");
487 ok(streamobj.writecalls == 0,"called Write() after read failure\n");
488 ok(streamobj.seekcalls == 2,"wrong Seek() call count (%d)\n", streamobj.seekcalls);
489
490 pSHFreeDataBlockList(list);
491}
492
494{
495 struct dummystream streamobj;
496 BOOL bRet;
497
498 if (!pSHIsEmptyStream)
499 return FALSE;
500
501 InitDummyStream(&streamobj);
502 bRet = pSHIsEmptyStream(&streamobj.IStream_iface);
503
504 if (bRet != TRUE)
505 return FALSE; /* This version doesn't support stream ops on clists */
506
507 ok(streamobj.readcalls == 0, "called Read()\n");
508 ok(streamobj.writecalls == 0, "called Write()\n");
509 ok(streamobj.seekcalls == 0, "called Seek()\n");
510 ok(streamobj.statcalls == 1, "wrong call count\n");
511
512 streamobj.statcalls = 0;
513 streamobj.pos.QuadPart = 50001;
514
515 bRet = pSHIsEmptyStream(&streamobj.IStream_iface);
516
517 ok(bRet == FALSE, "failed after seek adjusted\n");
518 ok(streamobj.readcalls == 0, "called Read()\n");
519 ok(streamobj.writecalls == 0, "called Write()\n");
520 ok(streamobj.seekcalls == 0, "called Seek()\n");
521 ok(streamobj.statcalls == 1, "wrong call count\n");
522
523 /* Failure cases */
524 InitDummyStream(&streamobj);
525 streamobj.pos.QuadPart = 50001;
526 streamobj.failstatcall = TRUE; /* 1: Stat() Bad, Read() OK */
527 bRet = pSHIsEmptyStream(&streamobj.IStream_iface);
528 ok(bRet == FALSE, "should be FALSE after read is OK\n");
529 ok(streamobj.readcalls == 1, "wrong call count\n");
530 ok(streamobj.writecalls == 0, "called Write()\n");
531 ok(streamobj.seekcalls == 1, "wrong call count\n");
532 ok(streamobj.statcalls == 1, "wrong call count\n");
533 ok(streamobj.pos.QuadPart == 0, "Didn't seek to start\n");
534
535 InitDummyStream(&streamobj);
536 streamobj.pos.QuadPart = 50001;
537 streamobj.failstatcall = TRUE;
538 streamobj.failreadcall = TRUE; /* 2: Stat() Bad, Read() Bad Also */
539 bRet = pSHIsEmptyStream(&streamobj.IStream_iface);
540 ok(bRet == TRUE, "Should be true after read fails\n");
541 ok(streamobj.readcalls == 1, "wrong call count\n");
542 ok(streamobj.writecalls == 0, "called Write()\n");
543 ok(streamobj.seekcalls == 0, "Called Seek()\n");
544 ok(streamobj.statcalls == 1, "wrong call count\n");
545 ok(streamobj.pos.QuadPart == 50001, "called Seek() after read failed\n");
546 return TRUE;
547}
548
549static void test_IStream_Read(void)
550{
551 struct dummystream streamobj;
552 char buff[256];
553 HRESULT hRet;
554
555 if (!pIStream_Read)
556 return;
557
558 InitDummyStream(&streamobj);
559 hRet = pIStream_Read(&streamobj.IStream_iface, buff, sizeof(buff));
560
561 ok(hRet == S_OK, "failed Read()\n");
562 ok(streamobj.readcalls == 1, "wrong call count\n");
563 ok(streamobj.writecalls == 0, "called Write()\n");
564 ok(streamobj.seekcalls == 0, "called Seek()\n");
565}
566
567static void test_IStream_Write(void)
568{
569 struct dummystream streamobj;
570 char buff[256] = {0};
571 HRESULT hRet;
572
573 if (!pIStream_Write)
574 return;
575
576 InitDummyStream(&streamobj);
577 hRet = pIStream_Write(&streamobj.IStream_iface, buff, sizeof(buff));
578
579 ok(hRet == S_OK, "failed Write()\n");
580 ok(streamobj.readcalls == 0, "called Read()\n");
581 ok(streamobj.writecalls == 1, "wrong call count\n");
582 ok(streamobj.seekcalls == 0, "called Seek()\n");
583}
584
585static void test_IStream_Reset(void)
586{
587 struct dummystream streamobj;
590 HRESULT hRet;
591
592 if (!pIStream_Reset || !pIStream_Size)
593 return;
594
595 InitDummyStream(&streamobj);
596 ll.QuadPart = 5000l;
597 Seek(&streamobj.IStream_iface, ll, 0, NULL); /* Seek to 5000l */
598
599 streamobj.seekcalls = 0;
600 pIStream_Reset(&streamobj.IStream_iface);
601 ok(streamobj.statcalls == 0, "called Stat()\n");
602 ok(streamobj.readcalls == 0, "called Read()\n");
603 ok(streamobj.writecalls == 0, "called Write()\n");
604 ok(streamobj.seekcalls == 1, "wrong call count\n");
605
606 ul.QuadPart = 50001;
607 hRet = pIStream_Size(&streamobj.IStream_iface, &ul);
608 ok(hRet == S_OK, "failed Stat()\n");
609 ok(ul.QuadPart == 0, "213 didn't rewind stream\n");
610}
611
612static void test_IStream_Size(void)
613{
614 struct dummystream streamobj;
617 HRESULT hRet;
618
619 if (!pIStream_Size)
620 return;
621
622 InitDummyStream(&streamobj);
623 ll.QuadPart = 5000l;
624 Seek(&streamobj.IStream_iface, ll, 0, NULL);
625 ul.QuadPart = 0;
626 streamobj.seekcalls = 0;
627 hRet = pIStream_Size(&streamobj.IStream_iface, &ul);
628
629 ok(hRet == S_OK, "failed Stat()\n");
630 ok(streamobj.statcalls == 1, "wrong call count\n");
631 ok(streamobj.readcalls == 0, "called Read()\n");
632 ok(streamobj.writecalls == 0, "called Write()\n");
633 ok(streamobj.seekcalls == 0, "called Seek()\n");
634 ok(ul.QuadPart == 5000l, "Stat gave wrong size\n");
635}
636
638{
639 if(!InitFunctionPtrs())
640 return;
641
642 test_CList();
643
644 /* Test streaming if this version supports it */
646 {
651 }
652}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:20
#define U(x)
Definition: wordpad.c:45
const GUID IID_IUnknown
w ll
Definition: byte_order.h:167
_In_ BOOLEAN Release
Definition: cdrom.h:920
Definition: list.h:37
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcAddress(x, y)
Definition: compat.h:753
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
return ret
Definition: mutex.c:146
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
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
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define Stat
Definition: syshdrs.h:78
#define win_skip
Definition: minitest.h:67
static ULARGE_INTEGER *static BOOL InitFunctionPtrs(void)
Definition: clist.c:227
static HRESULT WINAPI QueryInterface(IStream *iface, REFIID riid, void **ret_iface)
Definition: clist.c:71
static HRESULT WINAPI Write(IStream *iface, const void *lpMem, ULONG ulSize, ULONG *lpWritten)
Definition: clist.c:148
static HRESULT WINAPI Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: clist.c:167
static BOOL test_SHIsEmptyStream(void)
Definition: clist.c:493
static void test_IStream_Reset(void)
Definition: clist.c:585
static DATABLOCK_HEADER *WINAPI * pSHFindDataBlock(DATABLOCK_HEADER *, ULONG)
static const DATABLOCK_HEADER clist_items[]
Definition: clist.c:30
static void test_CList(void)
Definition: clist.c:283
static void test_IStream_Size(void)
Definition: clist.c:612
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:83
static void InitDummyStream(struct dummystream *obj)
Definition: clist.c:263
static struct dummystream * impl_from_IStream(IStream *iface)
Definition: clist.c:66
static void test_IStream_Write(void)
Definition: clist.c:567
static IStreamVtbl iclvt
Definition: clist.c:192
static void test_IStream_Read(void)
Definition: clist.c:549
static HMODULE SHLWAPI_hshlwapi
Definition: clist.c:211
#define BOOL
Definition: nt_native.h:43
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
struct tagDATABLOCKHEADER DATABLOCK_HEADER
_In_ BOOLEAN Read
Definition: strmini.h:479
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
BOOL readbeyondend
Definition: clist.c:54
int writecalls
Definition: clist.c:56
BOOL failwritecall
Definition: clist.c:57
const DATABLOCK_HEADER * item
Definition: clist.c:62
BOOL failreadcall
Definition: clist.c:52
ULARGE_INTEGER pos
Definition: clist.c:63
int readcalls
Definition: clist.c:51
int statcalls
Definition: clist.c:60
int seekcalls
Definition: clist.c:59
BOOL failwritesize
Definition: clist.c:58
BOOL failstatcall
Definition: clist.c:61
BOOL readreturnlarge
Definition: clist.c:55
LONG ref
Definition: clist.c:50
IStream IStream_iface
Definition: clist.c:49
BOOL failreadsize
Definition: clist.c:53
unsigned char * LPBYTE
Definition: typedefs.h:53
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:3479
#define STG_E_ACCESSDENIED
Definition: winerror.h:3663
#define STG_E_MEDIUMFULL
Definition: winerror.h:3676
char * LPSTR
Definition: xmlstorage.h:182
unsigned char BYTE
Definition: xxhash.c:193