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