Moved all the content of the DDK files ntdef.h and ntddk.h to
[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 %lld %d %d", ulLong, i, cPos);
448   }
449   cPos = pRtlFindMostSignificantBit(0);
450   ok (cPos == -1, "found bit when not set");
451 }
452
453 static void test_RtlFindLeastSignificantBit()
454 {
455   int i;
456   CCHAR cPos;
457   ULONGLONG ulLong;
458
459   if (!pRtlFindLeastSignificantBit)
460     return;
461
462   for (i = 0; i < 64; i++)
463   {
464     ulLong = 1ul;
465     ulLong <<= i;
466
467     cPos = pRtlFindLeastSignificantBit(ulLong);
468     ok (cPos == i, "didnt find LSB at %d", cPos);
469   }
470   cPos = pRtlFindLeastSignificantBit(0);
471   ok (cPos == -1, "found bit when not set");
472 }
473
474 /* Note: Also tests RtlFindLongestRunSet() */
475 static void test_RtlFindSetRuns()
476 {
477   RTL_BITMAP_RUN runs[16];
478   ULONG ulCount;
479
480   if (!pRtlFindSetRuns)
481     return;
482
483   pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
484
485   memset(buff, 0, sizeof(buff));
486   ulCount = pRtlFindSetRuns(&bm, runs, 16, TRUE);
487   ok (ulCount == 0, "found set bits in empty bitmap");
488
489   memset(runs, 0, sizeof(runs));
490   memset(buff, 0xff, sizeof(buff));
491   ulCount = pRtlFindSetRuns(&bm, runs, 16, TRUE);
492   ok (ulCount == 1, "didnt find set bits");
493   ok (runs[0].StartOfRun == 0,"bad start");
494   ok (runs[0].SizeOfRun == sizeof(buff)*8,"bad size");
495
496   /* Set up 3 runs */
497   memset(runs, 0, sizeof(runs));
498   memset(buff, 0, sizeof(buff));
499   pRtlSetBits(&bm, 7, 19);
500   pRtlSetBits(&bm, 101, 3);
501   pRtlSetBits(&bm, 1877, 33);
502
503   /* Get first 2 */
504   ulCount = pRtlFindSetRuns(&bm, runs, 2, FALSE);
505   ok (runs[0].StartOfRun == 7 || runs[0].StartOfRun == 101,"bad find");
506   ok (runs[1].StartOfRun == 7 || runs[1].StartOfRun == 101,"bad find");
507   ok (runs[0].SizeOfRun + runs[1].SizeOfRun == 19 + 3,"bad size");
508   ok (runs[0].StartOfRun != runs[1].StartOfRun,"found run twice");
509   ok (runs[2].StartOfRun == 0,"found extra run");
510
511   /* Get longest 3 */
512   memset(runs, 0, sizeof(runs));
513   ulCount = pRtlFindSetRuns(&bm, runs, 2, TRUE);
514   ok (runs[0].StartOfRun == 7 || runs[0].StartOfRun == 1877,"bad find");
515   ok (runs[1].StartOfRun == 7 || runs[1].StartOfRun == 1877,"bad find");
516   ok (runs[0].SizeOfRun + runs[1].SizeOfRun == 33 + 19,"bad size");
517   ok (runs[0].StartOfRun != runs[1].StartOfRun,"found run twice");
518   ok (runs[2].StartOfRun == 0,"found extra run");
519
520   /* Get all 3 */
521   memset(runs, 0, sizeof(runs));
522   ulCount = pRtlFindSetRuns(&bm, runs, 3, TRUE);
523   ok (runs[0].StartOfRun == 7 || runs[0].StartOfRun == 101 ||
524       runs[0].StartOfRun == 1877,"bad find");
525   ok (runs[1].StartOfRun == 7 || runs[1].StartOfRun == 101 ||
526       runs[1].StartOfRun == 1877,"bad find");
527   ok (runs[2].StartOfRun == 7 || runs[2].StartOfRun == 101 ||
528       runs[2].StartOfRun == 1877,"bad find");
529   ok (runs[0].SizeOfRun + runs[1].SizeOfRun
530       + runs[2].SizeOfRun == 19 + 3 + 33,"bad size");
531   ok (runs[0].StartOfRun != runs[1].StartOfRun,"found run twice");
532   ok (runs[1].StartOfRun != runs[2].StartOfRun,"found run twice");
533   ok (runs[3].StartOfRun == 0,"found extra run");
534
535   if (pRtlFindLongestRunSet)
536   {
537     ULONG ulStart = 0;
538
539     ulCount = pRtlFindLongestRunSet(&bm, &ulStart);
540     ok(ulCount == 33 && ulStart == 1877,"didn't find longest %ld %ld",ulCount,ulStart);
541
542     memset(buff, 0, sizeof(buff));
543     ulCount = pRtlFindLongestRunSet(&bm, &ulStart);
544     ok(ulCount == 0,"found longest when none set");
545   }
546 }
547
548 /* Note: Also tests RtlFindLongestRunClear() */
549 static void test_RtlFindClearRuns()
550 {
551   RTL_BITMAP_RUN runs[16];
552   ULONG ulCount;
553
554   if (!pRtlFindClearRuns)
555     return;
556
557   pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8);
558
559   memset(buff, 0xff, sizeof(buff));
560   ulCount = pRtlFindClearRuns(&bm, runs, 16, TRUE);
561   ok (ulCount == 0, "found clear bits in full bitmap");
562
563   memset(runs, 0, sizeof(runs));
564   memset(buff, 0, sizeof(buff));
565   ulCount = pRtlFindClearRuns(&bm, runs, 16, TRUE);
566   ok (ulCount == 1, "didnt find clear bits");
567   ok (runs[0].StartOfRun == 0,"bad start");
568   ok (runs[0].SizeOfRun == sizeof(buff)*8,"bad size");
569
570   /* Set up 3 runs */
571   memset(runs, 0, sizeof(runs));
572   memset(buff, 0xff, sizeof(buff));
573   pRtlClearBits(&bm, 7, 19);
574   pRtlClearBits(&bm, 101, 3);
575   pRtlClearBits(&bm, 1877, 33);
576
577   /* Get first 2 */
578   ulCount = pRtlFindClearRuns(&bm, runs, 2, FALSE);
579   ok (runs[0].StartOfRun == 7 || runs[0].StartOfRun == 101,"bad find");
580   ok (runs[1].StartOfRun == 7 || runs[1].StartOfRun == 101,"bad find");
581   ok (runs[0].SizeOfRun + runs[1].SizeOfRun == 19 + 3,"bad size");
582   ok (runs[0].StartOfRun != runs[1].StartOfRun,"found run twice");
583   ok (runs[2].StartOfRun == 0,"found extra run");
584
585   /* Get longest 3 */
586   memset(runs, 0, sizeof(runs));
587   ulCount = pRtlFindClearRuns(&bm, runs, 2, TRUE);
588   ok (runs[0].StartOfRun == 7 || runs[0].StartOfRun == 1877,"bad find");
589   ok (runs[1].StartOfRun == 7 || runs[1].StartOfRun == 1877,"bad find");
590   ok (runs[0].SizeOfRun + runs[1].SizeOfRun == 33 + 19,"bad size");
591   ok (runs[0].StartOfRun != runs[1].StartOfRun,"found run twice");
592   ok (runs[2].StartOfRun == 0,"found extra run");
593
594   /* Get all 3 */
595   memset(runs, 0, sizeof(runs));
596   ulCount = pRtlFindClearRuns(&bm, runs, 3, TRUE);
597   ok (runs[0].StartOfRun == 7 || runs[0].StartOfRun == 101 ||
598       runs[0].StartOfRun == 1877,"bad find");
599   ok (runs[1].StartOfRun == 7 || runs[1].StartOfRun == 101 ||
600       runs[1].StartOfRun == 1877,"bad find");
601   ok (runs[2].StartOfRun == 7 || runs[2].StartOfRun == 101 ||
602       runs[2].StartOfRun == 1877,"bad find");
603   ok (runs[0].SizeOfRun + runs[1].SizeOfRun
604       + runs[2].SizeOfRun == 19 + 3 + 33,"bad size");
605   ok (runs[0].StartOfRun != runs[1].StartOfRun,"found run twice");
606   ok (runs[1].StartOfRun != runs[2].StartOfRun,"found run twice");
607   ok (runs[3].StartOfRun == 0,"found extra run");
608
609   if (pRtlFindLongestRunClear)
610   {
611     ULONG ulStart = 0;
612
613     ulCount = pRtlFindLongestRunClear(&bm, &ulStart);
614     ok(ulCount == 33 && ulStart == 1877,"didn't find longest");
615
616     memset(buff, 0xff, sizeof(buff));
617     ulCount = pRtlFindLongestRunClear(&bm, &ulStart);
618     ok(ulCount == 0,"found longest when none clear");
619   }
620
621 }
622
623 START_TEST(rtlbitmap)
624 {
625   InitFunctionPtrs();
626
627   if (pRtlInitializeBitMap)
628   {
629     test_RtlInitializeBitMap();
630     test_RtlSetAllBits();
631     test_RtlClearAllBits();
632     test_RtlSetBits();
633     test_RtlClearBits();
634     test_RtlCheckBit();
635     test_RtlAreBitsSet();
636     test_RtlAreBitsClear();
637     test_RtlNumberOfSetBits();
638     test_RtlNumberOfClearBits();
639     test_RtlFindSetBitsAndClear();
640     test_RtlFindClearBitsAndSet();
641     test_RtlFindMostSignificantBit();
642     test_RtlFindLeastSignificantBit();
643     test_RtlFindSetRuns();
644     test_RtlFindClearRuns();
645   }
646 }