ReactOS 0.4.16-dev-125-g798ea90
dpa.c
Go to the documentation of this file.
1/*
2 * Unit tests for DPA functions
3 *
4 * Copyright 2003 Uwe Bonnes
5 * Copyright 2005 Felix Nawothnig
6 *
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.
11 *
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.
16 *
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
20 */
21
22#define COBJMACROS
23
24#include <stdarg.h>
25
26#include "windef.h"
27#include "winbase.h"
28#include "winuser.h"
29#include "commctrl.h"
30#include "objidl.h"
31
32#include "wine/test.h"
33#include "v6util.h"
34
35#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
36
37typedef struct _STREAMDATA
38{
43
44static HDPA (WINAPI *pDPA_Clone)(const HDPA,HDPA);
45static HDPA (WINAPI *pDPA_Create)(INT);
46static HDPA (WINAPI *pDPA_CreateEx)(INT,HANDLE);
47static PVOID (WINAPI *pDPA_DeleteAllPtrs)(HDPA);
48static PVOID (WINAPI *pDPA_DeletePtr)(HDPA,INT);
49static BOOL (WINAPI *pDPA_Destroy)(HDPA);
50static VOID (WINAPI *pDPA_DestroyCallback)(HDPA,PFNDPAENUMCALLBACK,PVOID);
51static VOID (WINAPI *pDPA_EnumCallback)(HDPA,PFNDPAENUMCALLBACK,PVOID);
52static INT (WINAPI *pDPA_GetPtr)(HDPA,INT);
53static INT (WINAPI *pDPA_GetPtrIndex)(HDPA,PVOID);
54static BOOL (WINAPI *pDPA_Grow)(HDPA,INT);
55static INT (WINAPI *pDPA_InsertPtr)(HDPA,INT,PVOID);
56static HRESULT (WINAPI *pDPA_LoadStream)(HDPA*,PFNDPASTREAM,IStream*,LPVOID);
58static HRESULT (WINAPI *pDPA_SaveStream)(HDPA,PFNDPASTREAM,IStream*,LPVOID);
60static BOOL (WINAPI *pDPA_SetPtr)(HDPA,INT,PVOID);
61static BOOL (WINAPI *pDPA_Sort)(HDPA,PFNDPACOMPARE,LPARAM);
62
63static void init_functions(void)
64{
65 HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
66
67#define X2(f, ord) p##f = (void*)GetProcAddress(hComCtl32, (const char *)ord);
68 /* 4.00+ */
69 X2(DPA_Clone, 331);
70 X2(DPA_Create, 328);
71 X2(DPA_CreateEx, 340);
73 X2(DPA_DeletePtr, 336);
74 X2(DPA_Destroy, 329);
75 X2(DPA_GetPtr, 332);
76 X2(DPA_GetPtrIndex, 333);
77 X2(DPA_Grow, 330);
78 X2(DPA_InsertPtr, 334);
79 X2(DPA_Search, 339);
80 X2(DPA_SetPtr, 335);
81 X2(DPA_Sort, 338);
82
83 /* 4.71+ */
85 X2(DPA_EnumCallback, 385);
87 X2(DPA_Merge, 11);
88 X2(DPA_SaveStream, 10);
89#undef X2
90}
91
92/* Callbacks */
94{
95 ok(lp == 0x1abe11ed, "lp=%ld\n", lp);
96 return p1 < p2 ? -1 : p1 > p2 ? 1 : 0;
97}
98
100{
101 ok(lp == 0x1abe11ed, "lp=%ld\n", lp);
102 return p1 > p2 ? -1 : p1 < p2 ? 1 : 0;
103}
104
105/* merge callback messages counter
106 DPAMM_MERGE 1
107 DPAMM_DELETE 2
108 DPAMM_INSERT 3 */
109static INT nMessages[4];
110
112{
113 nMessages[op]++;
114 ok(lp == 0x1abe11ed, "lp=%ld\n", lp);
115 return p1;
116}
117
119{
120 nMessages[op]++;
121 ok(lp == 0x1abe11ed, "lp=%ld\n", lp);
122 return ((PCHAR)p2)+1;
123}
124
125static INT nEnum;
126
128{
129 INT i;
130
131 i = pDPA_GetPtrIndex(lp, pItem);
132 ok(i == nEnum, "i=%d nEnum=%d\n", i, nEnum);
133 nEnum++;
134 pDPA_SetPtr(lp, i, (PVOID)7);
135 return pItem != (PVOID)3;
136}
137
139{
140 HRESULT hRes;
141
142 ok(lp == (LPVOID)0xdeadbeef, "lp=%p\n", lp);
143 hRes = IStream_Write(pStm, &pInfo->iPos, sizeof(INT), NULL);
144 expect(S_OK, hRes);
145 hRes = IStream_Write(pStm, &pInfo->pvItem, sizeof(PVOID), NULL);
146 expect(S_OK, hRes);
147 return S_OK;
148}
149
151{
152 HRESULT hRes;
153 INT iOldPos;
154
155 iOldPos = pInfo->iPos;
156 ok(lp == (LPVOID)0xdeadbeef, "lp=%p\n", lp);
157 hRes = IStream_Read(pStm, &pInfo->iPos, sizeof(INT), NULL);
158 expect(S_OK, hRes);
159 ok(pInfo->iPos == iOldPos, "iPos=%d iOldPos=%d\n", pInfo->iPos, iOldPos);
160 hRes = IStream_Read(pStm, &pInfo->pvItem, sizeof(PVOID), NULL);
161 expect(S_OK, hRes);
162 return S_OK;
163}
164
166{
167 DWORD dwOut = 0;
168 INT i;
169
170 for(i = 0; i < 8;)
171 {
172 ULONG_PTR ulItem = (ULONG_PTR)pDPA_GetPtr(dpa, i++);
173 if(!ulItem) break;
174 dwOut = dwOut << 4 | (ulItem & 0xf);
175 }
176
177 *pdwOut = dwOut;
178
179 if(dwOut != dwIn)
180 {
181 pDPA_DeleteAllPtrs(dpa);
182
183 do
184 {
185 pDPA_InsertPtr(dpa, 0, (PVOID)(ULONG_PTR)(dwIn & 0xf));
186 dwIn >>= 4;
187 }
188 while(dwIn);
189
190 return FALSE;
191 }
192
193 return TRUE;
194}
195
196static void test_dpa(void)
197{
198 SYSTEM_INFO si;
199 HANDLE hHeap;
200 HDPA dpa, dpa2, dpa3;
201 INT ret, i;
202 PVOID p;
203 DWORD dw, dw2, dw3;
204 BOOL rc;
205
206 GetSystemInfo(&si);
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);
213 "ret=%d error=%d\n", ret, GetLastError());
214
215 dpa = pDPA_Create(0);
216 ok(dpa != NULL, "\n");
217
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);
224
225 /* Prepend item */
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);
237
238 rc=CheckDPA(dpa, 0x516324, &dw);
239 ok(rc, "dw=0x%x\n", dw);
240
241 for(i = 1; i <= 6; i++)
242 {
243 INT j, k;
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);
248 }
249
250 /* Sort DPA */
251 ok(pDPA_Sort(dpa, CB_CmpGT, 0x1abe11ed), "\n");
252 rc=CheckDPA(dpa, 0x654321, &dw);
253 ok(rc, "dw=0x%x\n", dw);
254
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");
262
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);
268
269 /* Clone into an old DPA */
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);
275
276 for(i = 1; i <= 6; i++)
277 {
278 INT j;
279
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);
285
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);
292 }
293
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);
297
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);
303
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);
309
310 /* Check where to re-insert the deleted item */
311 i = pDPA_Search(dpa, (PVOID)3, 0,
313 ok(i == 2, "i=%d\n", i);
314 /* DPAS_INSERTBEFORE works just like DPAS_INSERTAFTER */
315 i = pDPA_Search(dpa, (PVOID)3, 0,
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);
322
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);
328
329 /* When doing a binary search while claiming reverse order all indexes
330 * should be bogus */
331 for(i = 0; i < 6; i++)
332 {
333 INT j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, 0, CB_CmpGT, 0x1abe11ed,
335 ok(j != i, "i=%d\n", i);
336 }
337
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);
342
343 pDPA_DeleteAllPtrs(dpa2);
344 rc=CheckDPA(dpa2, 0, &dw2);
345 ok(rc, "dw2=0x%x\n", dw2);
346
347 pDPA_Destroy(dpa);
348 pDPA_Destroy(dpa2);
349 pDPA_Destroy(dpa3);
350}
351
352static void test_DPA_Merge(void)
353{
354 HDPA dpa, dpa2, dpa3;
355 INT ret, i;
356 DWORD dw;
357 BOOL rc;
358
359 if(!pDPA_Merge)
360 {
361 win_skip("DPA_Merge() not available\n");
362 return;
363 }
364
365 dpa = pDPA_Create(0);
366 dpa2 = pDPA_Create(0);
367 dpa3 = pDPA_Create(0);
368
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);
375
376 rc = CheckDPA(dpa, 0x135, &dw);
377 ok(rc, "dw=0x%x\n", dw);
378
379 for (i = 0; i < 6; i++)
380 {
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);
385 }
386
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);
391
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);
398
402
403 for (i = 0; i < 6; i++)
404 {
405 ret = pDPA_InsertPtr(dpa2, i, (PVOID)(INT_PTR)(6-i));
406 ok(ret == i, "ret=%d\n", ret);
407 }
408
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);
415
419
420 /* DPAM_UNION */
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);
429
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);
434 ok(rc ||
435 broken(!rc && dw == 0x23456), /* 4.7x */
436 "dw=0x%x\n", dw);
437
440 ok(nMessages[DPAMM_INSERT] == 3 ||
441 broken(nMessages[DPAMM_INSERT] == 2), /* 4.7x */
442 "Expected 3, got %d\n", nMessages[DPAMM_INSERT]);
443
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);
451
452
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);
457
458 memset(nMessages, 0, sizeof(nMessages));
459 pDPA_Merge(dpa2, dpa3, DPAM_UNION|DPAM_SORTED,
460 CB_CmpLT, CB_MergeInsertSrc, 0x1abe11ed);
463 ok(nMessages[DPAMM_INSERT] == 3 ||
464 broken(nMessages[DPAMM_INSERT] == 2), /* 4.7x */
465 "Expected 3, got %d\n", nMessages[DPAMM_INSERT]);
466
467 rc = CheckDPA(dpa, 0x123456, &dw);
468 ok(rc, "dw=0x%x\n", dw);
469 rc = CheckDPA(dpa2, 0x123456, &dw);
470 ok(rc ||
471 broken(!rc), /* win98 */
472 "dw=0x%x\n", dw);
473 rc = CheckDPA(dpa3, 0x123456, &dw);
474 ok(rc, "dw=0x%x\n", dw);
475
476 pDPA_Destroy(dpa);
477 pDPA_Destroy(dpa2);
478 pDPA_Destroy(dpa3);
479}
480
481static void test_DPA_EnumCallback(void)
482{
483 HDPA dpa;
484 BOOL rc;
485 DWORD dw;
486 INT i, ret;
487
488 if(!pDPA_EnumCallback)
489 {
490 win_skip("DPA_EnumCallback() not available\n");
491 return;
492 }
493
494 dpa = pDPA_Create(0);
495
496 for (i = 0; i < 6; i++)
497 {
498 ret = pDPA_InsertPtr(dpa, i, (PVOID)(INT_PTR)(i+1));
499 ok(ret == i, "ret=%d\n", ret);
500 }
501
502 rc = CheckDPA(dpa, 0x123456, &dw);
503 ok(rc, "dw=0x%x\n", dw);
504
505 nEnum = 0;
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);
511
512 pDPA_Destroy(dpa);
513}
514
516{
517 HDPA dpa;
518 INT i, ret;
519
520 if(!pDPA_DestroyCallback)
521 {
522 win_skip("DPA_DestroyCallback() not available\n");
523 return;
524 }
525
526 dpa = pDPA_Create(0);
527
528 for (i = 0; i < 3; i++)
529 {
530 ret = pDPA_InsertPtr(dpa, i, (PVOID)(INT_PTR)(i+1));
531 ok(ret == i, "ret=%d\n", ret);
532 }
533
534 nEnum = 0;
535 pDPA_DestroyCallback(dpa, CB_EnumFirstThree, dpa);
536 ok(nEnum == 3, "nEnum=%d\n", nEnum);
537}
538
539static void test_DPA_LoadStream(void)
540{
541 static const WCHAR szStg[] = { 'S','t','g',0 };
542 IStorage* pStg = NULL;
543 IStream* pStm = NULL;
545 ULARGE_INTEGER uli;
546 DWORD dwMode;
547 HRESULT hRes;
549 ULONG written, ret;
550 HDPA dpa;
551
552 if(!pDPA_LoadStream)
553 {
554 win_skip("DPA_LoadStream() not available. Skipping stream tests.\n");
555 return;
556 }
557
558 hRes = CoInitialize(NULL);
559 if (hRes != S_OK)
560 {
561 ok(0, "hResult: %d\n", hRes);
562 return;
563 }
564
566 hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg);
567 expect(S_OK, hRes);
568
569 hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm);
570 expect(S_OK, hRes);
571
572 /* write less than header size */
573 li.QuadPart = 0;
574 hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
575 expect(S_OK, hRes);
576
577 memset(&header, 0, sizeof(header));
578 written = 0;
579 uli.QuadPart = sizeof(header)-1;
580 hRes = IStream_SetSize(pStm, uli);
581 expect(S_OK, hRes);
582 hRes = IStream_Write(pStm, &header, sizeof(header)-1, &written);
583 expect(S_OK, hRes);
584 written -= sizeof(header)-1;
585 expect(0, written);
586
587 li.QuadPart = 0;
588 hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
589 expect(S_OK, hRes);
590
591 hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, NULL);
592 expect(E_FAIL, hRes);
593
594 /* check stream position after header read failed */
595 li.QuadPart = 0;
596 uli.QuadPart = 1;
597 hRes = IStream_Seek(pStm, li, STREAM_SEEK_CUR, &uli);
598 expect(S_OK, hRes);
599 ok(uli.QuadPart == 0, "Expected to position reset\n");
600
601 /* write valid header for empty DPA */
602 header.dwSize = sizeof(header);
603 header.dwData2 = 1;
604 header.dwItems = 0;
605 written = 0;
606
607 li.QuadPart = 0;
608 hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
609 expect(S_OK, hRes);
610
611 uli.QuadPart = sizeof(header);
612 hRes = IStream_SetSize(pStm, uli);
613 expect(S_OK, hRes);
614
615 hRes = IStream_Write(pStm, &header, sizeof(header), &written);
616 expect(S_OK, hRes);
617 written -= sizeof(header);
618 expect(0, written);
619
620 li.QuadPart = 0;
621 hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
622 expect(S_OK, hRes);
623
624 dpa = NULL;
625 hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, NULL);
626 expect(S_OK, hRes);
627 pDPA_Destroy(dpa);
628
629 /* try with altered dwData2 field */
630 header.dwSize = sizeof(header);
631 header.dwData2 = 2;
632 header.dwItems = 0;
633
634 li.QuadPart = 0;
635 hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
636 expect(S_OK, hRes);
637 hRes = IStream_Write(pStm, &header, sizeof(header), &written);
638 expect(S_OK, hRes);
639 written -= sizeof(header);
640 expect(0, written);
641
642 li.QuadPart = 0;
643 hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
644 expect(S_OK, hRes);
645
646 hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, (void*)0xdeadbeef);
647 expect(E_FAIL, hRes);
648
649 ret = IStream_Release(pStm);
650 ok(!ret, "ret=%d\n", ret);
651
652 ret = IStorage_Release(pStg);
653 ok(!ret, "ret=%d\n", ret);
654
656}
657
658static void test_DPA_SaveStream(void)
659{
660 HDPA dpa;
661 static const WCHAR szStg[] = { 'S','t','g',0 };
662 IStorage* pStg = NULL;
663 IStream* pStm = NULL;
664 DWORD dwMode, dw;
665 HRESULT hRes;
666 INT ret;
667 INT i;
668 BOOL rc;
669 LARGE_INTEGER liZero;
670
671 if(!pDPA_SaveStream)
672 {
673 win_skip("DPA_SaveStream() not available. Skipping stream tests.\n");
674 return;
675 }
676
677 hRes = CoInitialize(NULL);
678 if (hRes != S_OK)
679 {
680 ok(0, "hResult: %d\n", hRes);
681 return;
682 }
683
685 hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg);
686 expect(S_OK, hRes);
687
688 hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm);
689 expect(S_OK, hRes);
690
691 dpa = pDPA_Create(0);
692
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);
697if (0) {
698 /* crashes on XP */
699 hRes = pDPA_SaveStream(NULL, CB_Save, pStm, NULL);
700 expect(E_INVALIDARG, hRes);
701
702 hRes = pDPA_SaveStream(dpa, CB_Save, NULL, NULL);
703 expect(E_INVALIDARG, hRes);
704}
705
706 /* saving/loading */
707 for (i = 0; i < 6; i++)
708 {
709 ret = pDPA_InsertPtr(dpa, i, (PVOID)(INT_PTR)(i+1));
710 ok(ret == i, "ret=%d\n", ret);
711 }
712
713 liZero.QuadPart = 0;
714 hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL);
715 expect(S_OK, hRes);
716
717 hRes = pDPA_SaveStream(dpa, CB_Save, pStm, (void*)0xdeadbeef);
718 expect(S_OK, hRes);
719 pDPA_Destroy(dpa);
720
721 liZero.QuadPart = 0;
722 hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL);
723 expect(S_OK, hRes);
724 hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, (void*)0xdeadbeef);
725 expect(S_OK, hRes);
726 rc = CheckDPA(dpa, 0x123456, &dw);
727 ok(rc, "dw=0x%x\n", dw);
728 pDPA_Destroy(dpa);
729
730 ret = IStream_Release(pStm);
731 ok(!ret, "ret=%d\n", ret);
732
733 ret = IStorage_Release(pStg);
734 ok(!ret, "ret=%d\n", ret);
735
737}
738
740{
742 HANDLE ctxt;
743
745
746 test_dpa();
752
753 if (!load_v6_module(&cookie, &ctxt))
754 return;
755
757
758 test_dpa();
764
766}
#define VOID
Definition: acefi.h:82
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
BOOL WINAPI DPA_Sort(HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
Definition: dpa.c:813
struct _STREAMDATA * PSTREAMDATA
INT WINAPI DPA_Search(HDPA hdpa, LPVOID pFind, INT nStart, PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions)
Definition: dpa.c:845
BOOL WINAPI DPA_Merge(HDPA hdpa1, HDPA hdpa2, DWORD dwFlags, PFNDPACOMPARE pfnCompare, PFNDPAMERGE pfnMerge, LPARAM lParam)
Definition: dpa.c:265
HDPA WINAPI DPA_Clone(const HDPA hdpa, HDPA hdpaNew)
Definition: dpa.c:470
HDPA WINAPI DPA_CreateEx(INT nGrow, HANDLE hHeap)
Definition: dpa.c:909
BOOL WINAPI DPA_SetPtr(HDPA hdpa, INT i, LPVOID p)
Definition: dpa.c:626
BOOL WINAPI DPA_DeleteAllPtrs(HDPA hdpa)
Definition: dpa.c:730
VOID WINAPI DPA_EnumCallback(HDPA hdpa, PFNDPAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dpa.c:969
HRESULT WINAPI DPA_LoadStream(HDPA *phDpa, PFNDPASTREAM loadProc, IStream *pStream, LPVOID pData)
Definition: dpa.c:82
HRESULT WINAPI DPA_SaveStream(HDPA hDpa, PFNDPASTREAM saveProc, IStream *pStream, LPVOID pData)
Definition: dpa.c:179
INT WINAPI DPA_GetPtrIndex(HDPA hdpa, LPCVOID p)
Definition: dpa.c:561
void WINAPI DPA_DestroyCallback(HDPA hdpa, PFNDPAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dpa.c:1003
BOOL WINAPI DPA_Grow(HDPA hdpa, INT nGrow)
Definition: dpa.c:423
LPVOID WINAPI DPA_DeletePtr(HDPA hdpa, INT i)
Definition: dpa.c:677
BOOL WINAPI DPA_Destroy(HDPA hdpa)
Definition: dpa.c:396
HDPA WINAPI DPA_Create(INT nGrow)
Definition: dpa.c:950
struct _STREAMDATA STREAMDATA
INT WINAPI DPA_InsertPtr(HDPA hdpa, INT i, LPVOID p)
Definition: dpa.c:591
#define SetLastError(x)
Definition: compat.h:752
#define CALLBACK
Definition: compat.h:35
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8636
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
LARGE_INTEGER li
Definition: fxtimerapi.cpp:235
GLfloat GLfloat p
Definition: glext.h:8902
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
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 GLint GLint j
Definition: glfuncs.h:250
HANDLE WINAPI HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
Definition: heapmem.c:45
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
#define S_OK
Definition: intsafe.h:52
#define X2(f, ord)
static void test_DPA_DestroyCallback(void)
Definition: dpa.c:515
static void test_DPA_SaveStream(void)
Definition: dpa.c:658
static HANDLE
Definition: dpa.c:46
static INT
Definition: dpa.c:48
static LPARAM
Definition: dpa.c:57
static INT CALLBACK CB_CmpGT(PVOID p1, PVOID p2, LPARAM lp)
Definition: dpa.c:99
static BOOL CheckDPA(HDPA dpa, DWORD dwIn, PDWORD pdwOut)
Definition: dpa.c:165
static INT CALLBACK CB_CmpLT(PVOID p1, PVOID p2, LPARAM lp)
Definition: dpa.c:93
static DWORD
Definition: dpa.c:57
static void test_DPA_Merge(void)
Definition: dpa.c:352
#define expect(expected, got)
Definition: dpa.c:35
static PVOID
Definition: dpa.c:50
static INT CALLBACK CB_EnumFirstThree(PVOID pItem, PVOID lp)
Definition: dpa.c:127
static PVOID CALLBACK CB_MergeInsertSrc(UINT op, PVOID p1, PVOID p2, LPARAM lp)
Definition: dpa.c:111
static HRESULT CALLBACK CB_Load(DPASTREAMINFO *pInfo, IStream *pStm, LPVOID lp)
Definition: dpa.c:150
static void test_DPA_LoadStream(void)
Definition: dpa.c:539
static HRESULT CALLBACK CB_Save(DPASTREAMINFO *pInfo, IStream *pStm, LPVOID lp)
Definition: dpa.c:138
static INT nMessages[4]
Definition: dpa.c:109
static HDPA
Definition: dpa.c:44
static void init_functions(void)
Definition: dpa.c:63
static void test_dpa(void)
Definition: dpa.c:196
static INT nEnum
Definition: dpa.c:125
static void test_DPA_EnumCallback(void)
Definition: dpa.c:481
static PVOID CALLBACK CB_MergeDeleteOddSrc(UINT op, PVOID p1, PVOID p2, LPARAM lp)
Definition: dpa.c:118
static UINT
Definition: dpa.c:59
int k
Definition: mpi.c:3369
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define LPVOID
Definition: nt_native.h:45
_Out_ PDWORD pdwOut
Definition: ntgdi.h:1813
_In_ UINT _In_ DWORD dwIn
Definition: ntgdi.h:249
#define STGM_CREATE
Definition: objbase.h:926
#define STGM_DIRECT
Definition: objbase.h:914
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define STGM_DELETEONRELEASE
Definition: objbase.h:925
DWORD * PDWORD
Definition: pedump.c:68
#define DPAS_INSERTBEFORE
Definition: commctrl.h:4868
void *(CALLBACK * PFNDPAMERGE)(_In_ UINT, _In_ void *, _In_ void *, _In_ LPARAM)
Definition: commctrl.h:4902
#define DPAMM_INSERT
Definition: commctrl.h:4974
#define DPAM_UNION
Definition: commctrl.h:4969
#define DPAS_SORTED
Definition: commctrl.h:4867
#define DPA_ERR
Definition: commctrl.h:4790
int(CALLBACK * PFNDPAENUMCALLBACK)(void *p, void *pData)
Definition: commctrl.h:4797
int(CALLBACK * PFNDPACOMPARE)(void *p1, void *p2, LPARAM lParam)
Definition: commctrl.h:4857
#define DPAMM_DELETE
Definition: commctrl.h:4973
#define DPAM_SORTED
Definition: commctrl.h:4967
HRESULT(CALLBACK * PFNDPASTREAM)(_In_ DPASTREAMINFO *, _In_ struct IStream *, _In_opt_ void *)
Definition: commctrl.h:4896
#define DPA_APPEND
Definition: commctrl.h:4789
#define DPAS_INSERTAFTER
Definition: commctrl.h:4869
#define DPAM_INTERSECT
Definition: commctrl.h:4970
#define DPAMM_MERGE
Definition: commctrl.h:4972
#define DPA_GetPtr
Definition: commctrl.h:5
#define win_skip
Definition: test.h:163
#define memset(x, y, z)
Definition: compat.h:39
void * pvItem
Definition: commctrl.h:4890
Definition: dpa.c:49
DWORD dwItems
Definition: dpa.c:61
DWORD dwSize
Definition: dpa.c:59
DWORD dwData2
Definition: dpa.c:60
DWORD dwPageSize
Definition: winbase.h:1173
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
Definition: cookie.c:34
int32_t INT_PTR
Definition: typedefs.h:64
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
LONGLONG QuadPart
Definition: typedefs.h:114
static BOOL load_v6_module(ULONG_PTR *pcookie, HANDLE *hCtx)
Definition: v6util.h:73
static void unload_v6_module(ULONG_PTR cookie, HANDLE hCtx)
Definition: v6util.h:65
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
LONG_PTR LPARAM
Definition: windef.h:208
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
__wchar_t WCHAR
Definition: xmlstorage.h:180