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