2 * Unit tests for DPA functions
4 * Copyright 2003 Uwe Bonnes
5 * Copyright 2005 Felix Nawothnig
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/test.h"
35 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
37 typedef struct _STREAMDATA
42 } STREAMDATA
, *PSTREAMDATA
;
44 static HDPA (WINAPI
*pDPA_Clone
)(const HDPA
,HDPA
);
45 static HDPA (WINAPI
*pDPA_Create
)(INT
);
46 static HDPA (WINAPI
*pDPA_CreateEx
)(INT
,HANDLE
);
47 static PVOID (WINAPI
*pDPA_DeleteAllPtrs
)(HDPA
);
48 static PVOID (WINAPI
*pDPA_DeletePtr
)(HDPA
,INT
);
49 static BOOL (WINAPI
*pDPA_Destroy
)(HDPA
);
50 static VOID (WINAPI
*pDPA_DestroyCallback
)(HDPA
,PFNDPAENUMCALLBACK
,PVOID
);
51 static VOID (WINAPI
*pDPA_EnumCallback
)(HDPA
,PFNDPAENUMCALLBACK
,PVOID
);
52 static INT (WINAPI
*pDPA_GetPtr
)(HDPA
,INT
);
53 static INT (WINAPI
*pDPA_GetPtrIndex
)(HDPA
,PVOID
);
54 static BOOL (WINAPI
*pDPA_Grow
)(HDPA
,INT
);
55 static INT (WINAPI
*pDPA_InsertPtr
)(HDPA
,INT
,PVOID
);
56 static HRESULT (WINAPI
*pDPA_LoadStream
)(HDPA
*,PFNDPASTREAM
,IStream
*,LPVOID
);
57 static BOOL (WINAPI
*pDPA_Merge
)(HDPA
,HDPA
,DWORD
,PFNDPACOMPARE
,PFNDPAMERGE
,LPARAM
);
58 static HRESULT (WINAPI
*pDPA_SaveStream
)(HDPA
,PFNDPASTREAM
,IStream
*,LPVOID
);
59 static INT (WINAPI
*pDPA_Search
)(HDPA
,PVOID
,INT
,PFNDPACOMPARE
,LPARAM
,UINT
);
60 static BOOL (WINAPI
*pDPA_SetPtr
)(HDPA
,INT
,PVOID
);
61 static BOOL (WINAPI
*pDPA_Sort
)(HDPA
,PFNDPACOMPARE
,LPARAM
);
63 static void init_functions(void)
65 HMODULE hComCtl32
= LoadLibraryA("comctl32.dll");
67 #define X2(f, ord) p##f = (void*)GetProcAddress(hComCtl32, (const char *)ord);
71 X2(DPA_CreateEx
, 340);
72 X2(DPA_DeleteAllPtrs
, 337);
73 X2(DPA_DeletePtr
, 336);
76 X2(DPA_GetPtrIndex
, 333);
78 X2(DPA_InsertPtr
, 334);
84 X2(DPA_DestroyCallback
, 386);
85 X2(DPA_EnumCallback
, 385);
86 X2(DPA_LoadStream
, 9);
88 X2(DPA_SaveStream
, 10);
93 static INT CALLBACK
CB_CmpLT(PVOID p1
, PVOID p2
, LPARAM lp
)
95 ok(lp
== 0x1abe11ed, "lp=%ld\n", lp
);
96 return p1
< p2
? -1 : p1
> p2
? 1 : 0;
99 static INT CALLBACK
CB_CmpGT(PVOID p1
, PVOID p2
, LPARAM lp
)
101 ok(lp
== 0x1abe11ed, "lp=%ld\n", lp
);
102 return p1
> p2
? -1 : p1
< p2
? 1 : 0;
105 /* merge callback messages counter
109 static INT nMessages
[4];
111 static PVOID CALLBACK
CB_MergeInsertSrc(UINT op
, PVOID p1
, PVOID p2
, LPARAM lp
)
114 ok(lp
== 0x1abe11ed, "lp=%ld\n", lp
);
118 static PVOID CALLBACK
CB_MergeDeleteOddSrc(UINT op
, PVOID p1
, PVOID p2
, LPARAM lp
)
121 ok(lp
== 0x1abe11ed, "lp=%ld\n", lp
);
122 return ((PCHAR
)p2
)+1;
127 static INT CALLBACK
CB_EnumFirstThree(PVOID pItem
, PVOID lp
)
131 i
= pDPA_GetPtrIndex(lp
, pItem
);
132 ok(i
== nEnum
, "i=%d nEnum=%d\n", i
, nEnum
);
134 pDPA_SetPtr(lp
, i
, (PVOID
)7);
135 return pItem
!= (PVOID
)3;
138 static HRESULT CALLBACK
CB_Save(DPASTREAMINFO
*pInfo
, IStream
*pStm
, LPVOID lp
)
142 ok(lp
== (LPVOID
)0xdeadbeef, "lp=%p\n", lp
);
143 hRes
= IStream_Write(pStm
, &pInfo
->iPos
, sizeof(INT
), NULL
);
145 hRes
= IStream_Write(pStm
, &pInfo
->pvItem
, sizeof(PVOID
), NULL
);
150 static HRESULT CALLBACK
CB_Load(DPASTREAMINFO
*pInfo
, IStream
*pStm
, LPVOID lp
)
155 iOldPos
= pInfo
->iPos
;
156 ok(lp
== (LPVOID
)0xdeadbeef, "lp=%p\n", lp
);
157 hRes
= IStream_Read(pStm
, &pInfo
->iPos
, sizeof(INT
), NULL
);
159 ok(pInfo
->iPos
== iOldPos
, "iPos=%d iOldPos=%d\n", pInfo
->iPos
, iOldPos
);
160 hRes
= IStream_Read(pStm
, &pInfo
->pvItem
, sizeof(PVOID
), NULL
);
165 static BOOL
CheckDPA(HDPA dpa
, DWORD dwIn
, PDWORD pdwOut
)
172 ULONG_PTR ulItem
= (ULONG_PTR
)pDPA_GetPtr(dpa
, i
++);
174 dwOut
= dwOut
<< 4 | (ulItem
& 0xf);
181 pDPA_DeleteAllPtrs(dpa
);
185 pDPA_InsertPtr(dpa
, 0, (PVOID
)(ULONG_PTR
)(dwIn
& 0xf));
196 static void test_dpa(void)
200 HDPA dpa
, dpa2
, dpa3
;
207 hHeap
= HeapCreate(0, 1, 2);
208 ok(hHeap
!= NULL
, "error=%d\n", GetLastError());
209 dpa3
= pDPA_CreateEx(0, hHeap
);
210 ok(dpa3
!= NULL
, "\n");
211 ret
= pDPA_Grow(dpa3
, si
.dwPageSize
+ 1);
212 ok(!ret
&& GetLastError() == ERROR_NOT_ENOUGH_MEMORY
,
213 "ret=%d error=%d\n", ret
, GetLastError());
215 dpa
= pDPA_Create(0);
216 ok(dpa
!= NULL
, "\n");
218 /* Set item with out of bound index */
219 ok(pDPA_SetPtr(dpa
, 1, (PVOID
)6), "\n");
220 /* Fill the created gap */
221 ok(pDPA_SetPtr(dpa
, 0, (PVOID
)5), "\n");
222 rc
=CheckDPA(dpa
, 0x56, &dw
);
223 ok(rc
, "dw=0x%x\n", dw
);
226 ret
= pDPA_InsertPtr(dpa
, 1, (PVOID
)1);
227 ok(ret
== 1, "ret=%d\n", ret
);
228 /* Append item using correct index */
229 ret
= pDPA_InsertPtr(dpa
, 3, (PVOID
)3);
230 ok(ret
== 3, "ret=%d\n", ret
);
231 /* Append item using out of bound index */
232 ret
= pDPA_InsertPtr(dpa
, 5, (PVOID
)2);
233 ok(ret
== 4, "ret=%d\n", ret
);
234 /* Append item using DPA_APPEND */
235 ret
= pDPA_InsertPtr(dpa
, DPA_APPEND
, (PVOID
)4);
236 ok(ret
== 5, "ret=%d\n", ret
);
238 rc
=CheckDPA(dpa
, 0x516324, &dw
);
239 ok(rc
, "dw=0x%x\n", dw
);
241 for(i
= 1; i
<= 6; i
++)
244 k
= pDPA_GetPtrIndex(dpa
, (PVOID
)(INT_PTR
)i
);
245 /* Linear searches should work on unsorted DPAs */
246 j
= pDPA_Search(dpa
, (PVOID
)(INT_PTR
)i
, 0, CB_CmpLT
, 0x1abe11ed, 0);
247 ok(j
== k
, "j=%d k=%d\n", j
, k
);
251 ok(pDPA_Sort(dpa
, CB_CmpGT
, 0x1abe11ed), "\n");
252 rc
=CheckDPA(dpa
, 0x654321, &dw
);
253 ok(rc
, "dw=0x%x\n", dw
);
255 /* Clone into a new DPA */
256 dpa2
= pDPA_Clone(dpa
, NULL
);
257 ok(dpa2
!= NULL
, "\n");
258 /* The old data should have been preserved */
259 rc
=CheckDPA(dpa2
, 0x654321, &dw2
);
260 ok(rc
, "dw=0x%x\n", dw2
);
261 ok(pDPA_Sort(dpa
, CB_CmpLT
, 0x1abe11ed), "\n");
263 /* Test if the DPA itself was really copied */
264 rc
=CheckDPA(dpa
, 0x123456, &dw
);
265 ok(rc
, "dw=0x%x\n", dw
);
266 rc
=CheckDPA(dpa2
, 0x654321, &dw2
);
267 ok(rc
, "dw2=0x%x\n", dw2
);
269 /* Clone into an old DPA */
270 SetLastError(ERROR_SUCCESS
);
271 p
= pDPA_Clone(dpa
, dpa3
);
272 ok(p
== dpa3
, "p=%p\n", p
);
273 rc
=CheckDPA(dpa3
, 0x123456, &dw3
);
274 ok(rc
, "dw3=0x%x\n", dw3
);
276 for(i
= 1; i
<= 6; i
++)
280 /* The array is in order so ptr == index+1 */
281 j
= pDPA_GetPtrIndex(dpa
, (PVOID
)(INT_PTR
)i
);
282 ok(j
+1 == i
, "j=%d i=%d\n", j
, i
);
283 j
= pDPA_Search(dpa
, (PVOID
)(INT_PTR
)i
, 0, CB_CmpLT
, 0x1abe11ed, DPAS_SORTED
);
284 ok(j
+1 == i
, "j=%d i=%d\n", j
, i
);
286 /* Linear searches respect iStart ... */
287 j
= pDPA_Search(dpa
, (PVOID
)(INT_PTR
)i
, i
+1, CB_CmpLT
, 0x1abe11ed, 0);
288 ok(j
== DPA_ERR
, "j=%d\n", j
);
289 /* ... but for a binary search it's ignored */
290 j
= pDPA_Search(dpa
, (PVOID
)(INT_PTR
)i
, i
+1, CB_CmpLT
, 0x1abe11ed, DPAS_SORTED
);
291 ok(j
+1 == i
, "j=%d i=%d\n", j
, i
);
294 /* Try to get the index of a nonexistent item */
295 i
= pDPA_GetPtrIndex(dpa
, (PVOID
)7);
296 ok(i
== DPA_ERR
, "i=%d\n", i
);
298 /* Try to delete out of bound indexes */
299 p
= pDPA_DeletePtr(dpa
, -1);
300 ok(p
== NULL
, "p=%p\n", p
);
301 p
= pDPA_DeletePtr(dpa
, 6);
302 ok(p
== NULL
, "p=%p\n", p
);
304 /* Delete the third item */
305 p
= pDPA_DeletePtr(dpa
, 2);
306 ok(p
== (PVOID
)3, "p=%p\n", p
);
307 rc
=CheckDPA(dpa
, 0x12456, &dw
);
308 ok(rc
, "dw=0x%x\n", dw
);
310 /* Check where to re-insert the deleted item */
311 i
= pDPA_Search(dpa
, (PVOID
)3, 0,
312 CB_CmpLT
, 0x1abe11ed, DPAS_SORTED
|DPAS_INSERTAFTER
);
313 ok(i
== 2, "i=%d\n", i
);
314 /* DPAS_INSERTBEFORE works just like DPAS_INSERTAFTER */
315 i
= pDPA_Search(dpa
, (PVOID
)3, 0,
316 CB_CmpLT
, 0x1abe11ed, DPAS_SORTED
|DPAS_INSERTBEFORE
);
317 ok(i
== 2, "i=%d\n", i
);
318 /* without DPAS_INSERTBEFORE/AFTER */
319 i
= pDPA_Search(dpa
, (PVOID
)3, 0,
320 CB_CmpLT
, 0x1abe11ed, DPAS_SORTED
);
321 ok(i
== -1, "i=%d\n", i
);
323 /* Re-insert the item */
324 ret
= pDPA_InsertPtr(dpa
, 2, (PVOID
)3);
325 ok(ret
== 2, "ret=%d i=%d\n", ret
, 2);
326 rc
=CheckDPA(dpa
, 0x123456, &dw
);
327 ok(rc
, "dw=0x%x\n", dw
);
329 /* When doing a binary search while claiming reverse order all indexes
331 for(i
= 0; i
< 6; i
++)
333 INT j
= pDPA_Search(dpa
, (PVOID
)(INT_PTR
)i
, 0, CB_CmpGT
, 0x1abe11ed,
334 DPAS_SORTED
|DPAS_INSERTBEFORE
);
335 ok(j
!= i
, "i=%d\n", i
);
338 /* Setting item with huge index should work */
339 ok(pDPA_SetPtr(dpa2
, 0x12345, (PVOID
)0xdeadbeef), "\n");
340 ret
= pDPA_GetPtrIndex(dpa2
, (PVOID
)0xdeadbeef);
341 ok(ret
== 0x12345, "ret=%d\n", ret
);
343 pDPA_DeleteAllPtrs(dpa2
);
344 rc
=CheckDPA(dpa2
, 0, &dw2
);
345 ok(rc
, "dw2=0x%x\n", dw2
);
352 static void test_DPA_Merge(void)
354 HDPA dpa
, dpa2
, dpa3
;
361 win_skip("DPA_Merge() not available\n");
365 dpa
= pDPA_Create(0);
366 dpa2
= pDPA_Create(0);
367 dpa3
= pDPA_Create(0);
369 ret
= pDPA_InsertPtr(dpa
, 0, (PVOID
)1);
370 ok(ret
== 0, "ret=%d\n", ret
);
371 ret
= pDPA_InsertPtr(dpa
, 1, (PVOID
)3);
372 ok(ret
== 1, "ret=%d\n", ret
);
373 ret
= pDPA_InsertPtr(dpa
, 2, (PVOID
)5);
374 ok(ret
== 2, "ret=%d\n", ret
);
376 rc
= CheckDPA(dpa
, 0x135, &dw
);
377 ok(rc
, "dw=0x%x\n", dw
);
379 for (i
= 0; i
< 6; i
++)
381 ret
= pDPA_InsertPtr(dpa2
, i
, (PVOID
)(INT_PTR
)(6-i
));
382 ok(ret
== i
, "ret=%d\n", ret
);
383 ret
= pDPA_InsertPtr(dpa3
, i
, (PVOID
)(INT_PTR
)(i
+1));
384 ok(ret
== i
, "ret=%d\n", ret
);
387 rc
= CheckDPA(dpa2
, 0x654321, &dw
);
388 ok(rc
, "dw=0x%x\n", dw
);
389 rc
= CheckDPA(dpa3
, 0x123456, &dw
);
390 ok(rc
, "dw=0x%x\n", dw
);
392 /* Delete all odd entries from dpa2 */
393 memset(nMessages
, 0, sizeof(nMessages
));
394 pDPA_Merge(dpa2
, dpa
, DPAM_INTERSECT
,
395 CB_CmpLT
, CB_MergeDeleteOddSrc
, 0x1abe11ed);
396 rc
= CheckDPA(dpa2
, 0x246, &dw
);
397 ok(rc
, "dw=0x%x\n", dw
);
399 expect(3, nMessages
[DPAMM_MERGE
]);
400 expect(3, nMessages
[DPAMM_DELETE
]);
401 expect(0, nMessages
[DPAMM_INSERT
]);
403 for (i
= 0; i
< 6; i
++)
405 ret
= pDPA_InsertPtr(dpa2
, i
, (PVOID
)(INT_PTR
)(6-i
));
406 ok(ret
== i
, "ret=%d\n", ret
);
409 /* DPAM_INTERSECT - returning source while merging */
410 memset(nMessages
, 0, sizeof(nMessages
));
411 pDPA_Merge(dpa2
, dpa
, DPAM_INTERSECT
,
412 CB_CmpLT
, CB_MergeInsertSrc
, 0x1abe11ed);
413 rc
= CheckDPA(dpa2
, 0x135, &dw
);
414 ok(rc
, "dw=0x%x\n", dw
);
416 expect(3, nMessages
[DPAMM_MERGE
]);
417 expect(6, nMessages
[DPAMM_DELETE
]);
418 expect(0, nMessages
[DPAMM_INSERT
]);
421 pDPA_DeleteAllPtrs(dpa
);
422 pDPA_InsertPtr(dpa
, 0, (PVOID
)1);
423 pDPA_InsertPtr(dpa
, 1, (PVOID
)3);
424 pDPA_InsertPtr(dpa
, 2, (PVOID
)5);
425 pDPA_DeleteAllPtrs(dpa2
);
426 pDPA_InsertPtr(dpa2
, 0, (PVOID
)2);
427 pDPA_InsertPtr(dpa2
, 1, (PVOID
)4);
428 pDPA_InsertPtr(dpa2
, 2, (PVOID
)6);
430 memset(nMessages
, 0, sizeof(nMessages
));
431 pDPA_Merge(dpa2
, dpa
, DPAM_UNION
,
432 CB_CmpLT
, CB_MergeInsertSrc
, 0x1abe11ed);
433 rc
= CheckDPA(dpa2
, 0x123456, &dw
);
435 broken(!rc
&& dw
== 0x23456), /* 4.7x */
438 expect(0, nMessages
[DPAMM_MERGE
]);
439 expect(0, nMessages
[DPAMM_DELETE
]);
440 ok(nMessages
[DPAMM_INSERT
] == 3 ||
441 broken(nMessages
[DPAMM_INSERT
] == 2), /* 4.7x */
442 "Expected 3, got %d\n", nMessages
[DPAMM_INSERT
]);
444 /* Merge dpa3 into dpa2 and dpa */
445 memset(nMessages
, 0, sizeof(nMessages
));
446 pDPA_Merge(dpa
, dpa3
, DPAM_UNION
|DPAM_SORTED
,
447 CB_CmpLT
, CB_MergeInsertSrc
, 0x1abe11ed);
448 expect(3, nMessages
[DPAMM_MERGE
]);
449 expect(0, nMessages
[DPAMM_DELETE
]);
450 expect(3, nMessages
[DPAMM_INSERT
]);
453 pDPA_DeleteAllPtrs(dpa2
);
454 pDPA_InsertPtr(dpa2
, 0, (PVOID
)2);
455 pDPA_InsertPtr(dpa2
, 1, (PVOID
)4);
456 pDPA_InsertPtr(dpa2
, 2, (PVOID
)6);
458 memset(nMessages
, 0, sizeof(nMessages
));
459 pDPA_Merge(dpa2
, dpa3
, DPAM_UNION
|DPAM_SORTED
,
460 CB_CmpLT
, CB_MergeInsertSrc
, 0x1abe11ed);
461 expect(3, nMessages
[DPAMM_MERGE
]);
462 expect(0, nMessages
[DPAMM_DELETE
]);
463 ok(nMessages
[DPAMM_INSERT
] == 3 ||
464 broken(nMessages
[DPAMM_INSERT
] == 2), /* 4.7x */
465 "Expected 3, got %d\n", nMessages
[DPAMM_INSERT
]);
467 rc
= CheckDPA(dpa
, 0x123456, &dw
);
468 ok(rc
, "dw=0x%x\n", dw
);
469 rc
= CheckDPA(dpa2
, 0x123456, &dw
);
471 broken(!rc
), /* win98 */
473 rc
= CheckDPA(dpa3
, 0x123456, &dw
);
474 ok(rc
, "dw=0x%x\n", dw
);
481 static void test_DPA_EnumCallback(void)
488 if(!pDPA_EnumCallback
)
490 win_skip("DPA_EnumCallback() not available\n");
494 dpa
= pDPA_Create(0);
496 for (i
= 0; i
< 6; i
++)
498 ret
= pDPA_InsertPtr(dpa
, i
, (PVOID
)(INT_PTR
)(i
+1));
499 ok(ret
== i
, "ret=%d\n", ret
);
502 rc
= CheckDPA(dpa
, 0x123456, &dw
);
503 ok(rc
, "dw=0x%x\n", dw
);
506 /* test callback sets first 3 items to 7 */
507 pDPA_EnumCallback(dpa
, CB_EnumFirstThree
, dpa
);
508 rc
= CheckDPA(dpa
, 0x777456, &dw
);
509 ok(rc
, "dw=0x%x\n", dw
);
510 ok(nEnum
== 3, "nEnum=%d\n", nEnum
);
515 static void test_DPA_DestroyCallback(void)
520 if(!pDPA_DestroyCallback
)
522 win_skip("DPA_DestroyCallback() not available\n");
526 dpa
= pDPA_Create(0);
528 for (i
= 0; i
< 3; i
++)
530 ret
= pDPA_InsertPtr(dpa
, i
, (PVOID
)(INT_PTR
)(i
+1));
531 ok(ret
== i
, "ret=%d\n", ret
);
535 pDPA_DestroyCallback(dpa
, CB_EnumFirstThree
, dpa
);
536 ok(nEnum
== 3, "nEnum=%d\n", nEnum
);
539 static void test_DPA_LoadStream(void)
541 static const WCHAR szStg
[] = { 'S','t','g',0 };
542 IStorage
* pStg
= NULL
;
543 IStream
* pStm
= NULL
;
554 win_skip("DPA_LoadStream() not available. Skipping stream tests.\n");
558 hRes
= CoInitialize(NULL
);
561 ok(0, "hResult: %d\n", hRes
);
565 dwMode
= STGM_DIRECT
|STGM_CREATE
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
;
566 hRes
= StgCreateDocfile(NULL
, dwMode
|STGM_DELETEONRELEASE
, 0, &pStg
);
569 hRes
= IStorage_CreateStream(pStg
, szStg
, dwMode
, 0, 0, &pStm
);
572 /* write less than header size */
574 hRes
= IStream_Seek(pStm
, li
, STREAM_SEEK_SET
, NULL
);
577 memset(&header
, 0, sizeof(header
));
579 uli
.QuadPart
= sizeof(header
)-1;
580 hRes
= IStream_SetSize(pStm
, uli
);
582 hRes
= IStream_Write(pStm
, &header
, sizeof(header
)-1, &written
);
584 written
-= sizeof(header
)-1;
588 hRes
= IStream_Seek(pStm
, li
, STREAM_SEEK_SET
, NULL
);
591 hRes
= pDPA_LoadStream(&dpa
, CB_Load
, pStm
, NULL
);
592 expect(E_FAIL
, hRes
);
594 /* check stream position after header read failed */
597 hRes
= IStream_Seek(pStm
, li
, STREAM_SEEK_CUR
, &uli
);
599 ok(uli
.QuadPart
== 0, "Expected to position reset\n");
601 /* write valid header for empty DPA */
602 header
.dwSize
= sizeof(header
);
608 hRes
= IStream_Seek(pStm
, li
, STREAM_SEEK_SET
, NULL
);
611 uli
.QuadPart
= sizeof(header
);
612 hRes
= IStream_SetSize(pStm
, uli
);
615 hRes
= IStream_Write(pStm
, &header
, sizeof(header
), &written
);
617 written
-= sizeof(header
);
621 hRes
= IStream_Seek(pStm
, li
, STREAM_SEEK_SET
, NULL
);
625 hRes
= pDPA_LoadStream(&dpa
, CB_Load
, pStm
, NULL
);
629 /* try with altered dwData2 field */
630 header
.dwSize
= sizeof(header
);
635 hRes
= IStream_Seek(pStm
, li
, STREAM_SEEK_SET
, NULL
);
637 hRes
= IStream_Write(pStm
, &header
, sizeof(header
), &written
);
639 written
-= sizeof(header
);
643 hRes
= IStream_Seek(pStm
, li
, STREAM_SEEK_SET
, NULL
);
646 hRes
= pDPA_LoadStream(&dpa
, CB_Load
, pStm
, (void*)0xdeadbeef);
647 expect(E_FAIL
, hRes
);
649 ret
= IStream_Release(pStm
);
650 ok(!ret
, "ret=%d\n", ret
);
652 ret
= IStorage_Release(pStg
);
653 ok(!ret
, "ret=%d\n", ret
);
658 static void test_DPA_SaveStream(void)
661 static const WCHAR szStg
[] = { 'S','t','g',0 };
662 IStorage
* pStg
= NULL
;
663 IStream
* pStm
= NULL
;
669 LARGE_INTEGER liZero
;
673 win_skip("DPA_SaveStream() not available. Skipping stream tests.\n");
677 hRes
= CoInitialize(NULL
);
680 ok(0, "hResult: %d\n", hRes
);
684 dwMode
= STGM_DIRECT
|STGM_CREATE
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
;
685 hRes
= StgCreateDocfile(NULL
, dwMode
|STGM_DELETEONRELEASE
, 0, &pStg
);
688 hRes
= IStorage_CreateStream(pStg
, szStg
, dwMode
, 0, 0, &pStm
);
691 dpa
= pDPA_Create(0);
693 /* simple parameter check */
694 hRes
= pDPA_SaveStream(dpa
, NULL
, pStm
, NULL
);
695 ok(hRes
== E_INVALIDARG
||
696 broken(hRes
== S_OK
) /* XP and below */, "Wrong result, %d\n", hRes
);
699 hRes
= pDPA_SaveStream(NULL
, CB_Save
, pStm
, NULL
);
700 expect(E_INVALIDARG
, hRes
);
702 hRes
= pDPA_SaveStream(dpa
, CB_Save
, NULL
, NULL
);
703 expect(E_INVALIDARG
, hRes
);
707 for (i
= 0; i
< 6; i
++)
709 ret
= pDPA_InsertPtr(dpa
, i
, (PVOID
)(INT_PTR
)(i
+1));
710 ok(ret
== i
, "ret=%d\n", ret
);
714 hRes
= IStream_Seek(pStm
, liZero
, STREAM_SEEK_SET
, NULL
);
717 hRes
= pDPA_SaveStream(dpa
, CB_Save
, pStm
, (void*)0xdeadbeef);
722 hRes
= IStream_Seek(pStm
, liZero
, STREAM_SEEK_SET
, NULL
);
724 hRes
= pDPA_LoadStream(&dpa
, CB_Load
, pStm
, (void*)0xdeadbeef);
726 rc
= CheckDPA(dpa
, 0x123456, &dw
);
727 ok(rc
, "dw=0x%x\n", dw
);
730 ret
= IStream_Release(pStm
);
731 ok(!ret
, "ret=%d\n", ret
);
733 ret
= IStorage_Release(pStg
);
734 ok(!ret
, "ret=%d\n", ret
);
748 test_DPA_EnumCallback();
749 test_DPA_DestroyCallback();
750 test_DPA_LoadStream();
751 test_DPA_SaveStream();
753 if (!load_v6_module(&cookie
, &ctxt
))
760 test_DPA_EnumCallback();
761 test_DPA_DestroyCallback();
762 test_DPA_LoadStream();
763 test_DPA_SaveStream();
765 unload_v6_module(cookie
, ctxt
);