[SHELL32] SHChangeNotify: Add drive, remove drive (#6782)
[reactos.git] / modules / rostests / winetests / ntdll / rtlbitmap.c
1 /* Unit test suite for Rtl bitmap 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 * NOTES
20 * We use function pointers here as some of the bitmap functions exist only
21 * in later versions of ntdll.
22 */
23
24 #include "ntdll_test.h"
25
26 #ifdef __WINE_WINTERNL_H
27
28 /* Function ptrs for ordinal calls */
29 static HMODULE hntdll = 0;
30 static VOID (WINAPI *pRtlInitializeBitMap)(PRTL_BITMAP,LPBYTE,ULONG);
31 static VOID (WINAPI *pRtlSetAllBits)(PRTL_BITMAP);
32 static VOID (WINAPI *pRtlClearAllBits)(PRTL_BITMAP);
33 static VOID (WINAPI *pRtlSetBits)(PRTL_BITMAP,ULONG,ULONG);
34 static VOID (WINAPI *pRtlClearBits)(PRTL_BITMAP,ULONG,ULONG);
35 static BOOLEAN (WINAPI *pRtlAreBitsSet)(PRTL_BITMAP,ULONG,ULONG);
36 static BOOLEAN (WINAPI *pRtlAreBitsClear)(PRTL_BITMAP,ULONG,ULONG);
37 static ULONG (WINAPI *pRtlFindSetBitsAndClear)(PRTL_BITMAP,ULONG,ULONG);
38 static ULONG (WINAPI *pRtlFindClearBitsAndSet)(PRTL_BITMAP,ULONG,ULONG);
39 static CCHAR (WINAPI *pRtlFindMostSignificantBit)(ULONGLONG);
40 static CCHAR (WINAPI *pRtlFindLeastSignificantBit)(ULONGLONG);
41 static ULONG (WINAPI *pRtlFindSetRuns)(PRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN);
42 static ULONG (WINAPI *pRtlFindClearRuns)(PRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN);
43 static ULONG (WINAPI *pRtlNumberOfSetBits)(PRTL_BITMAP);
44 static ULONG (WINAPI *pRtlNumberOfClearBits)(PRTL_BITMAP);
45 static ULONG (WINAPI *pRtlFindLongestRunSet)(PRTL_BITMAP,PULONG);
46 static ULONG (WINAPI *pRtlFindLongestRunClear)(PRTL_BITMAP,PULONG);
47
48 static BYTE buff[256];
49 static RTL_BITMAP bm;
50
51 static void InitFunctionPtrs(void)
52 {
53 hntdll = LoadLibraryA("ntdll.dll");
54 ok(hntdll != 0, "LoadLibrary failed\n");
55 if (hntdll)
56 {
57 pRtlInitializeBitMap = (void *)GetProcAddress(hntdll, "RtlInitializeBitMap");
58 pRtlSetAllBits = (void *)GetProcAddress(hntdll, "RtlSetAllBits");
59 pRtlClearAllBits = (void *)GetProcAddress(hntdll, "RtlClearAllBits");
60 pRtlSetBits = (void *)GetProcAddress(hntdll, "RtlSetBits");
61 pRtlClearBits = (void *)GetProcAddress(hntdll, "RtlClearBits");
62 pRtlAreBitsSet = (void *)GetProcAddress(hntdll, "RtlAreBitsSet");
63 pRtlAreBitsClear = (void *)GetProcAddress(hntdll, "RtlAreBitsClear");
64 pRtlNumberOfSetBits = (void *)GetProcAddress(hntdll, "RtlNumberOfSetBits");
65 pRtlNumberOfClearBits = (void *)GetProcAddress(hntdll, "RtlNumberOfClearBits");
66 pRtlFindSetBitsAndClear = (void *)GetProcAddress(hntdll, "RtlFindSetBitsAndClear");
67 pRtlFindClearBitsAndSet = (void *)GetProcAddress(hntdll, "RtlFindClearBitsAndSet");
68 pRtlFindMostSignificantBit = (void *)GetProcAddress(hntdll, "RtlFindMostSignificantBit");
69 pRtlFindLeastSignificantBit = (void *)GetProcAddress(hntdll, "RtlFindLeastSignificantBit");
70 pRtlFindSetRuns = (void *)GetProcAddress(hntdll, "RtlFindSetRuns");
71 pRtlFindClearRuns = (void *)GetProcAddress(hntdll, "RtlFindClearRuns");
72 pRtlFindLongestRunSet = (void *)GetProcAddress(hntdll, "RtlFindLongestRunSet");
73 pRtlFindLongestRunClear = (void *)GetProcAddress(hntdll, "RtlFindLongestRunClear");
74 }
75 }
76
77 static void test_RtlInitializeBitMap(void)
78 {
79 bm.SizeOfBitMap = 0;
80 bm.Buffer = 0;
81
82 memset(buff, 0, sizeof(buff));
83 buff[0] = 77; /* Check buffer is not written to during init */
84 buff[79] = 77;
85
86 pRtlInitializeBitMap(&bm, buff, 800);
87 ok(bm.SizeOfBitMap == 800, "size uninitialised\n");
88 ok(bm.Buffer == (PULONG)buff,"buffer uninitialised\n");
89 ok(buff[0] == 77 && buff[79] == 77, "wrote to buffer\n");
90 }
91
92 static void test_RtlSetAllBits(void)
93 {
94 if (!pRtlSetAllBits)
95 return;
96
97 memset(buff, 0 , sizeof(buff));
98 pRtlInitializeBitMap(&bm, buff, 1);
99
100 pRtlSetAllBits(&bm);
101 ok(buff[0] == 0xff && buff[1] == 0xff && buff[2] == 0xff &&
102 buff[3] == 0xff, "didn't round up size\n");
103 ok(buff[4] == 0, "set more than rounded size\n");
104 }
105
106 static void test_RtlClearAllBits(void)
107 {
108 if (!pRtlClearAllBits)
109 return;
110
111 memset(buff, 0xff , sizeof(buff));
112 pRtlInitializeBitMap(&bm, buff, 1);
113
114 pRtlClearAllBits(&bm);
115 ok(!buff[0] && !buff[1] && !buff[2] && !buff[3], "didn't round up size\n");
116 ok(buff[4] == 0xff, "cleared more than rounded size\n");
117 }
118
119 static void test_RtlSetBits(void)
120 {
121 if (!pRtlSetBits)
122 return;
123
124 memset(buff, 0 , sizeof(buff));
125 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
126
127 pRtlSetBits(&bm, 0, 1);
128 ok(buff[0] == 1, "didn't set 1st bit\n");
129
130 buff[0] = 0;
131 pRtlSetBits(&bm, 7, 2);
132 ok(buff[0] == 0x80 && buff[1] == 1, "didn't span w/len < 8\n");
133
134 buff[0] = buff[1] = 0;
135 pRtlSetBits(&bm, 7, 10);
136 ok(buff[0] == 0x80 && buff[1] == 0xff && buff[2] == 1, "didn't span w/len > 8\n");
137
138 buff[0] = buff[1] = buff[2] = 0;
139 pRtlSetBits(&bm, 0, 8); /* 1st byte */
140 ok(buff[0] == 0xff, "didn't set all bits\n");
141 ok(!buff[1], "set too many bits\n");
142
143 pRtlSetBits(&bm, sizeof(buff)*8-1, 1); /* last bit */
144 ok(buff[sizeof(buff)-1] == 0x80, "didn't set last bit\n");
145 }
146
147 static void test_RtlClearBits(void)
148 {
149 if (!pRtlClearBits)
150 return;
151
152 memset(buff, 0xff , sizeof(buff));
153 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
154
155 pRtlClearBits(&bm, 0, 1);
156 ok(buff[0] == 0xfe, "didn't clear 1st bit\n");
157
158 buff[0] = 0xff;
159 pRtlClearBits(&bm, 7, 2);
160 ok(buff[0] == 0x7f && buff[1] == 0xfe, "didn't span w/len < 8\n");
161
162 buff[0] = buff[1] = 0xff;
163 pRtlClearBits(&bm, 7, 10);
164 ok(buff[0] == 0x7f && buff[1] == 0 && buff[2] == 0xfe, "didn't span w/len > 8\n");
165
166 buff[0] = buff[1] = buff[2] = 0xff;
167 pRtlClearBits(&bm, 0, 8); /* 1st byte */
168 ok(!buff[0], "didn't clear all bits\n");
169 ok(buff[1] == 0xff, "cleared too many bits\n");
170
171 pRtlClearBits(&bm, sizeof(buff)*8-1, 1);
172 ok(buff[sizeof(buff)-1] == 0x7f, "didn't set last bit\n");
173 }
174
175 static void test_RtlCheckBit(void)
176 {
177 BOOLEAN bRet;
178
179 memset(buff, 0 , sizeof(buff));
180 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
181 pRtlSetBits(&bm, 0, 1);
182 pRtlSetBits(&bm, 7, 2);
183 pRtlSetBits(&bm, sizeof(buff)*8-1, 1);
184
185 bRet = RtlCheckBit(&bm, 0);
186 ok (bRet, "didn't find set bit\n");
187 bRet = RtlCheckBit(&bm, 7);
188 ok (bRet, "didn't find set bit\n");
189 bRet = RtlCheckBit(&bm, 8);
190 ok (bRet, "didn't find set bit\n");
191 bRet = RtlCheckBit(&bm, sizeof(buff)*8-1);
192 ok (bRet, "didn't find set bit\n");
193 bRet = RtlCheckBit(&bm, 1);
194 ok (!bRet, "found non set bit\n");
195 bRet = RtlCheckBit(&bm, sizeof(buff)*8-2);
196 ok (!bRet, "found non set bit\n");
197 }
198
199 static void test_RtlAreBitsSet(void)
200 {
201 BOOLEAN bRet;
202
203 if (!pRtlAreBitsSet)
204 return;
205
206 memset(buff, 0 , sizeof(buff));
207 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
208
209 bRet = pRtlAreBitsSet(&bm, 0, 1);
210 ok (!bRet, "found set bits after init\n");
211
212 pRtlSetBits(&bm, 0, 1);
213 bRet = pRtlAreBitsSet(&bm, 0, 1);
214 ok (bRet, "didn't find set bits\n");
215
216 buff[0] = 0;
217 pRtlSetBits(&bm, 7, 2);
218 bRet = pRtlAreBitsSet(&bm, 7, 2);
219 ok(bRet, "didn't find w/len < 8\n");
220 bRet = pRtlAreBitsSet(&bm, 6, 3);
221 ok(!bRet, "found non set bit\n");
222 bRet = pRtlAreBitsSet(&bm, 7, 3);
223 ok(!bRet, "found non set bit\n");
224
225 buff[0] = buff[1] = 0;
226 pRtlSetBits(&bm, 7, 10);
227 bRet = pRtlAreBitsSet(&bm, 7, 10);
228 ok(bRet, "didn't find w/len < 8\n");
229 bRet = pRtlAreBitsSet(&bm, 6, 11);
230 ok(!bRet, "found non set bit\n");
231 bRet = pRtlAreBitsSet(&bm, 7, 11);
232 ok(!bRet, "found non set bit\n");
233
234 buff[0] = buff[1] = buff[2] = 0;
235 pRtlSetBits(&bm, 0, 8); /* 1st byte */
236 bRet = pRtlAreBitsSet(&bm, 0, 8);
237 ok(bRet, "didn't find whole byte\n");
238
239 pRtlSetBits(&bm, sizeof(buff)*8-1, 1);
240 bRet = pRtlAreBitsSet(&bm, sizeof(buff)*8-1, 1);
241 ok(bRet, "didn't find last bit\n");
242 }
243
244 static void test_RtlAreBitsClear(void)
245 {
246 BOOLEAN bRet;
247
248 if (!pRtlAreBitsClear)
249 return;
250
251 memset(buff, 0xff , sizeof(buff));
252 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
253
254 bRet = pRtlAreBitsClear(&bm, 0, 1);
255 ok (!bRet, "found clear bits after init\n");
256
257 pRtlClearBits(&bm, 0, 1);
258 bRet = pRtlAreBitsClear(&bm, 0, 1);
259 ok (bRet, "didn't find set bits\n");
260
261 buff[0] = 0xff;
262 pRtlClearBits(&bm, 7, 2);
263 bRet = pRtlAreBitsClear(&bm, 7, 2);
264 ok(bRet, "didn't find w/len < 8\n");
265 bRet = pRtlAreBitsClear(&bm, 6, 3);
266 ok(!bRet, "found non clear bit\n");
267 bRet = pRtlAreBitsClear(&bm, 7, 3);
268 ok(!bRet, "found non clear bit\n");
269
270 buff[0] = buff[1] = 0xff;
271 pRtlClearBits(&bm, 7, 10);
272 bRet = pRtlAreBitsClear(&bm, 7, 10);
273 ok(bRet, "didn't find w/len < 8\n");
274 bRet = pRtlAreBitsClear(&bm, 6, 11);
275 ok(!bRet, "found non clear bit\n");
276 bRet = pRtlAreBitsClear(&bm, 7, 11);
277 ok(!bRet, "found non clear bit\n");
278
279 buff[0] = buff[1] = buff[2] = 0xff;
280 pRtlClearBits(&bm, 0, 8); /* 1st byte */
281 bRet = pRtlAreBitsClear(&bm, 0, 8);
282 ok(bRet, "didn't find whole byte\n");
283
284 pRtlClearBits(&bm, sizeof(buff)*8-1, 1);
285 bRet = pRtlAreBitsClear(&bm, sizeof(buff)*8-1, 1);
286 ok(bRet, "didn't find last bit\n");
287 }
288
289 static void test_RtlNumberOfSetBits(void)
290 {
291 ULONG ulCount;
292
293 if (!pRtlNumberOfSetBits)
294 return;
295
296 memset(buff, 0 , sizeof(buff));
297 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
298
299 ulCount = pRtlNumberOfSetBits(&bm);
300 ok(ulCount == 0, "set bits after init\n");
301
302 pRtlSetBits(&bm, 0, 1); /* Set 1st bit */
303 ulCount = pRtlNumberOfSetBits(&bm);
304 ok(ulCount == 1, "count wrong\n");
305
306 pRtlSetBits(&bm, 7, 8); /* 8 more, spanning bytes 1-2 */
307 ulCount = pRtlNumberOfSetBits(&bm);
308 ok(ulCount == 8+1, "count wrong\n");
309
310 pRtlSetBits(&bm, 17, 33); /* 33 more crossing ULONG boundary */
311 ulCount = pRtlNumberOfSetBits(&bm);
312 ok(ulCount == 8+1+33, "count wrong\n");
313
314 pRtlSetBits(&bm, sizeof(buff)*8-1, 1); /* Set last bit */
315 ulCount = pRtlNumberOfSetBits(&bm);
316 ok(ulCount == 8+1+33+1, "count wrong\n");
317 }
318
319 static void test_RtlNumberOfClearBits(void)
320 {
321 ULONG ulCount;
322
323 if (!pRtlNumberOfClearBits)
324 return;
325
326 memset(buff, 0xff , sizeof(buff));
327 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
328
329 ulCount = pRtlNumberOfClearBits(&bm);
330 ok(ulCount == 0, "cleared bits after init\n");
331
332 pRtlClearBits(&bm, 0, 1); /* Set 1st bit */
333 ulCount = pRtlNumberOfClearBits(&bm);
334 ok(ulCount == 1, "count wrong\n");
335
336 pRtlClearBits(&bm, 7, 8); /* 8 more, spanning bytes 1-2 */
337 ulCount = pRtlNumberOfClearBits(&bm);
338 ok(ulCount == 8+1, "count wrong\n");
339
340 pRtlClearBits(&bm, 17, 33); /* 33 more crossing ULONG boundary */
341 ulCount = pRtlNumberOfClearBits(&bm);
342 ok(ulCount == 8+1+33, "count wrong\n");
343
344 pRtlClearBits(&bm, sizeof(buff)*8-1, 1); /* Set last bit */
345 ulCount = pRtlNumberOfClearBits(&bm);
346 ok(ulCount == 8+1+33+1, "count wrong\n");
347 }
348
349 /* Note: this tests RtlFindSetBits also */
350 static void test_RtlFindSetBitsAndClear(void)
351 {
352 BOOLEAN bRet;
353 ULONG ulPos;
354
355 if (!pRtlFindSetBitsAndClear)
356 return;
357
358 memset(buff, 0, sizeof(buff));
359 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
360
361 pRtlSetBits(&bm, 0, 32);
362 ulPos = pRtlFindSetBitsAndClear(&bm, 32, 0);
363 ok (ulPos == 0, "didn't find bits\n");
364 if(ulPos == 0)
365 {
366 bRet = pRtlAreBitsClear(&bm, 0, 32);
367 ok (bRet, "found but didn't clear\n");
368 }
369
370 memset(buff, 0 , sizeof(buff));
371 pRtlSetBits(&bm, 40, 77);
372 ulPos = pRtlFindSetBitsAndClear(&bm, 77, 0);
373 ok (ulPos == 40, "didn't find bits\n");
374 if(ulPos == 40)
375 {
376 bRet = pRtlAreBitsClear(&bm, 40, 77);
377 ok (bRet, "found but didn't clear\n");
378 }
379 }
380
381 /* Note: this tests RtlFindClearBits also */
382 static void test_RtlFindClearBitsAndSet(void)
383 {
384 BOOLEAN bRet;
385 ULONG ulPos;
386
387 if (!pRtlFindClearBitsAndSet)
388 return;
389
390 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
391
392 memset(buff, 0xff, sizeof(buff));
393 pRtlSetBits(&bm, 0, 32);
394 ulPos = pRtlFindSetBitsAndClear(&bm, 32, 0);
395 ok (ulPos == 0, "didn't find bits\n");
396 if(ulPos == 0)
397 {
398 bRet = pRtlAreBitsClear(&bm, 0, 32);
399 ok (bRet, "found but didn't clear\n");
400 }
401
402 memset(buff, 0xff , sizeof(buff));
403 pRtlClearBits(&bm, 40, 77);
404 ulPos = pRtlFindClearBitsAndSet(&bm, 77, 50);
405 ok (ulPos == 40, "didn't find bits\n");
406 if(ulPos == 40)
407 {
408 bRet = pRtlAreBitsSet(&bm, 40, 77);
409 ok (bRet, "found but didn't set\n");
410 }
411 }
412
413 static void test_RtlFindMostSignificantBit(void)
414 {
415 int i;
416 signed char cPos;
417 ULONGLONG ulLong;
418
419 if (!pRtlFindMostSignificantBit)
420 return;
421
422 for (i = 0; i < 64; i++)
423 {
424 ulLong = 1ul;
425 ulLong <<= i;
426
427 cPos = pRtlFindMostSignificantBit(ulLong);
428 ok (cPos == i, "didn't find MSB 0x%s %d %d\n",
429 wine_dbgstr_longlong(ulLong ), i, cPos);
430
431 /* Set all bits lower than bit i */
432 ulLong = ((ulLong - 1) << 1) | 1;
433
434 cPos = pRtlFindMostSignificantBit(ulLong);
435 ok (cPos == i, "didn't find MSB 0x%s %d %d\n",
436 wine_dbgstr_longlong(ulLong ), i, cPos);
437 }
438 cPos = pRtlFindMostSignificantBit(0);
439 ok (cPos == -1, "found bit when not set\n");
440 }
441
442 static void test_RtlFindLeastSignificantBit(void)
443 {
444 int i;
445 signed char cPos;
446 ULONGLONG ulLong;
447
448 if (!pRtlFindLeastSignificantBit)
449 return;
450
451 for (i = 0; i < 64; i++)
452 {
453 ulLong = (ULONGLONG)1 << i;
454
455 cPos = pRtlFindLeastSignificantBit(ulLong);
456 ok (cPos == i, "didn't find LSB 0x%s %d %d\n",
457 wine_dbgstr_longlong(ulLong ), i, cPos);
458
459 ulLong = ~((ULONGLONG)0) << i;
460
461 cPos = pRtlFindLeastSignificantBit(ulLong);
462 ok (cPos == i, "didn't find LSB 0x%s %d %d\n",
463 wine_dbgstr_longlong(ulLong ), i, cPos);
464 }
465 cPos = pRtlFindLeastSignificantBit(0);
466 ok (cPos == -1, "found bit when not set\n");
467 }
468
469 /* Note: Also tests RtlFindLongestRunSet() */
470 static void test_RtlFindSetRuns(void)
471 {
472 RTL_BITMAP_RUN runs[16];
473 ULONG ulCount;
474
475 if (!pRtlFindSetRuns)
476 return;
477
478 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
479
480 memset(buff, 0, sizeof(buff));
481 ulCount = pRtlFindSetRuns(&bm, runs, 16, TRUE);
482 ok (ulCount == 0, "found set bits in empty bitmap\n");
483
484 memset(runs, 0, sizeof(runs));
485 memset(buff, 0xff, sizeof(buff));
486 ulCount = pRtlFindSetRuns(&bm, runs, 16, TRUE);
487 ok (ulCount == 1, "didn't find set bits\n");
488 ok (runs[0].StartingIndex == 0,"bad start\n");
489 ok (runs[0].NumberOfBits == sizeof(buff)*8,"bad size\n");
490
491 /* Set up 3 runs */
492 memset(runs, 0, sizeof(runs));
493 memset(buff, 0, sizeof(buff));
494 pRtlSetBits(&bm, 7, 19);
495 pRtlSetBits(&bm, 101, 3);
496 pRtlSetBits(&bm, 1877, 33);
497
498 /* Get first 2 */
499 ulCount = pRtlFindSetRuns(&bm, runs, 2, FALSE);
500 ok(ulCount == 2, "RtlFindClearRuns returned %d, expected 2\n", ulCount);
501 ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 101,"bad find\n");
502 ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 101,"bad find\n");
503 ok (runs[0].NumberOfBits + runs[1].NumberOfBits == 19 + 3,"bad size\n");
504 ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n");
505 ok (runs[2].StartingIndex == 0,"found extra run\n");
506
507 /* Get longest 3 */
508 memset(runs, 0, sizeof(runs));
509 ulCount = pRtlFindSetRuns(&bm, runs, 2, TRUE);
510 ok(ulCount == 2, "RtlFindClearRuns returned %d, expected 2\n", ulCount);
511 ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 1877,"bad find\n");
512 ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 1877,"bad find\n");
513 ok (runs[0].NumberOfBits + runs[1].NumberOfBits == 33 + 19,"bad size\n");
514 ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n");
515 ok (runs[2].StartingIndex == 0,"found extra run\n");
516
517 /* Get all 3 */
518 memset(runs, 0, sizeof(runs));
519 ulCount = pRtlFindSetRuns(&bm, runs, 3, TRUE);
520 ok(ulCount == 3, "RtlFindClearRuns returned %d, expected 3\n", ulCount);
521 ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 101 ||
522 runs[0].StartingIndex == 1877,"bad find\n");
523 ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 101 ||
524 runs[1].StartingIndex == 1877,"bad find\n");
525 ok (runs[2].StartingIndex == 7 || runs[2].StartingIndex == 101 ||
526 runs[2].StartingIndex == 1877,"bad find\n");
527 ok (runs[0].NumberOfBits + runs[1].NumberOfBits
528 + runs[2].NumberOfBits == 19 + 3 + 33,"bad size\n");
529 ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n");
530 ok (runs[1].StartingIndex != runs[2].StartingIndex,"found run twice\n");
531 ok (runs[3].StartingIndex == 0,"found extra run\n");
532
533 if (pRtlFindLongestRunSet)
534 {
535 ULONG ulStart = 0;
536
537 ulCount = pRtlFindLongestRunSet(&bm, &ulStart);
538 ok(ulCount == 33 && ulStart == 1877,"didn't find longest %d %d\n",ulCount,ulStart);
539
540 memset(buff, 0, sizeof(buff));
541 ulCount = pRtlFindLongestRunSet(&bm, &ulStart);
542 ok(ulCount == 0,"found longest when none set\n");
543 }
544 }
545
546 /* Note: Also tests RtlFindLongestRunClear() */
547 static void test_RtlFindClearRuns(void)
548 {
549 RTL_BITMAP_RUN runs[16];
550 ULONG ulCount;
551
552 if (!pRtlFindClearRuns)
553 return;
554
555 pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
556
557 memset(buff, 0xff, sizeof(buff));
558 ulCount = pRtlFindClearRuns(&bm, runs, 16, TRUE);
559 ok (ulCount == 0, "found clear bits in full bitmap\n");
560
561 memset(runs, 0, sizeof(runs));
562 memset(buff, 0, sizeof(buff));
563 ulCount = pRtlFindClearRuns(&bm, runs, 16, TRUE);
564 ok (ulCount == 1, "didn't find clear bits\n");
565 ok (runs[0].StartingIndex == 0,"bad start\n");
566 ok (runs[0].NumberOfBits == sizeof(buff)*8,"bad size\n");
567
568 /* Set up 3 runs */
569 memset(runs, 0, sizeof(runs));
570 memset(buff, 0xff, sizeof(buff));
571 pRtlClearBits(&bm, 7, 19);
572 pRtlClearBits(&bm, 101, 3);
573 pRtlClearBits(&bm, 1877, 33);
574
575 /* Get first 2 */
576 ulCount = pRtlFindClearRuns(&bm, runs, 2, FALSE);
577 ok(ulCount == 2, "RtlFindClearRuns returned %d, expected 2\n", ulCount);
578 ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 101,"bad find\n");
579 ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 101,"bad find\n");
580 ok (runs[0].NumberOfBits + runs[1].NumberOfBits == 19 + 3,"bad size\n");
581 ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n");
582 ok (runs[2].StartingIndex == 0,"found extra run\n");
583
584 /* Get longest 3 */
585 memset(runs, 0, sizeof(runs));
586 ulCount = pRtlFindClearRuns(&bm, runs, 2, TRUE);
587 ok(ulCount == 2, "RtlFindClearRuns returned %d, expected 2\n", ulCount);
588 ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 1877,"bad find\n");
589 ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 1877,"bad find\n");
590 ok (runs[0].NumberOfBits + runs[1].NumberOfBits == 33 + 19,"bad size\n");
591 ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n");
592 ok (runs[2].StartingIndex == 0,"found extra run\n");
593
594 /* Get all 3 */
595 memset(runs, 0, sizeof(runs));
596 ulCount = pRtlFindClearRuns(&bm, runs, 3, TRUE);
597 ok(ulCount == 3, "RtlFindClearRuns returned %d, expected 3\n", ulCount);
598 ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 101 ||
599 runs[0].StartingIndex == 1877,"bad find\n");
600 ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 101 ||
601 runs[1].StartingIndex == 1877,"bad find\n");
602 ok (runs[2].StartingIndex == 7 || runs[2].StartingIndex == 101 ||
603 runs[2].StartingIndex == 1877,"bad find\n");
604 ok (runs[0].NumberOfBits + runs[1].NumberOfBits
605 + runs[2].NumberOfBits == 19 + 3 + 33,"bad size\n");
606 ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n");
607 ok (runs[1].StartingIndex != runs[2].StartingIndex,"found run twice\n");
608 ok (runs[3].StartingIndex == 0,"found extra run\n");
609
610 if (pRtlFindLongestRunClear)
611 {
612 ULONG ulStart = 0;
613
614 ulCount = pRtlFindLongestRunClear(&bm, &ulStart);
615 ok(ulCount == 33 && ulStart == 1877,"didn't find longest\n");
616
617 memset(buff, 0xff, sizeof(buff));
618 ulCount = pRtlFindLongestRunClear(&bm, &ulStart);
619 ok(ulCount == 0,"found longest when none clear\n");
620 }
621
622 }
623 #endif
624
625 START_TEST(rtlbitmap)
626 {
627 #ifdef __WINE_WINTERNL_H
628 InitFunctionPtrs();
629
630 if (pRtlInitializeBitMap)
631 {
632 test_RtlInitializeBitMap();
633 test_RtlSetAllBits();
634 test_RtlClearAllBits();
635 test_RtlSetBits();
636 test_RtlClearBits();
637 test_RtlCheckBit();
638 test_RtlAreBitsSet();
639 test_RtlAreBitsClear();
640 test_RtlNumberOfSetBits();
641 test_RtlNumberOfClearBits();
642 test_RtlFindSetBitsAndClear();
643 test_RtlFindClearBitsAndSet();
644 test_RtlFindMostSignificantBit();
645 test_RtlFindLeastSignificantBit();
646 test_RtlFindSetRuns();
647 test_RtlFindClearRuns();
648 }
649 #endif
650 }