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 } 651