#undef BitScanForward
#define BitScanForward(Index, Mask) \
do { unsigned long tmp; BitScanForward64(&tmp, Mask); *Index = tmp; } while (0)
+#undef BitScanReverse
+#define BitScanReverse(Index, Mask) \
+ do { unsigned long tmp; BitScanReverse64(&tmp, Mask); *Index = tmp; } while (0)
#define RtlFillMemoryUlong RtlFillMemoryUlonglong
#define RtlInitializeBitMap RtlInitializeBitMap64
BITMAP_INDEX Value, BitPos, Length;
PBITMAP_BUFFER Buffer, MaxBuffer;
+ /* If we are already at the end, the length of the run is zero */
+ ASSERT(StartingIndex <= BitMapHeader->SizeOfBitMap);
+ if (StartingIndex >= BitMapHeader->SizeOfBitMap)
+ return 0;
+
/* Calculate positions */
Buffer = BitMapHeader->Buffer + StartingIndex / _BITCOUNT;
BitPos = StartingIndex & (_BITCOUNT - 1);
BITMAP_INDEX InvValue, BitPos, Length;
PBITMAP_BUFFER Buffer, MaxBuffer;
+ /* If we are already at the end, the length of the run is zero */
+ ASSERT(StartingIndex <= BitMapHeader->SizeOfBitMap);
+ if (StartingIndex >= BitMapHeader->SizeOfBitMap)
+ return 0;
+
/* Calculate positions */
Buffer = BitMapHeader->Buffer + StartingIndex / _BITCOUNT;
BitPos = StartingIndex & (_BITCOUNT - 1);
/* Clear what's left */
NumberToClear &= (_BITCOUNT - 1);
- Mask = MAXINDEX << NumberToClear;
- *Buffer &= Mask;
+ if (NumberToClear != 0)
+ {
+ Mask = MAXINDEX << NumberToClear;
+ *Buffer &= Mask;
+ }
}
VOID
/* Set what's left */
NumberToSet &= (_BITCOUNT - 1);
- Mask = MAXINDEX << NumberToSet;
- *Buffer |= ~Mask;
+ if (NumberToSet != 0)
+ {
+ Mask = MAXINDEX << NumberToSet;
+ *Buffer |= ~Mask;
+ }
}
BOOLEAN
BitCount += BitCountTable[*Byte++];
}
- Shift = 8 - (BitMapHeader->SizeOfBitMap & 7);
- BitCount += BitCountTable[((*Byte) << Shift) & 0xFF];
+ if (BitMapHeader->SizeOfBitMap & 7)
+ {
+ Shift = 8 - (BitMapHeader->SizeOfBitMap & 7);
+ BitCount += BitCountTable[((*Byte) << Shift) & 0xFF];
+ }
return BitCount;
}
*StartingRunIndex = FromIndex + Length;
/* Now return the length of the run */
- return RtlpGetLengthOfRunSet(BitMapHeader, FromIndex, MAXINDEX);
+ return RtlpGetLengthOfRunSet(BitMapHeader, FromIndex + Length, MAXINDEX);
}
BITMAP_INDEX
return RtlFindNextForwardRunClear(BitMapHeader, 0, StartingIndex);
}
-ULONG
+BITMAP_INDEX
NTAPI
RtlFindLastBackwardRunClear(
_In_ PRTL_BITMAP BitMapHeader,
_In_ BITMAP_INDEX FromIndex,
_Out_ PBITMAP_INDEX StartingRunIndex)
{
- UNIMPLEMENTED;
- return 0;
+ BITMAP_INDEX Value, InvValue, BitPos;
+ PBITMAP_BUFFER Buffer;
+
+ /* Make sure we don't go past the end */
+ FromIndex = min(FromIndex, BitMapHeader->SizeOfBitMap - 1);
+
+ /* Calculate positions */
+ Buffer = BitMapHeader->Buffer + FromIndex / _BITCOUNT;
+ BitPos = (_BITCOUNT - 1) - (FromIndex & (_BITCOUNT - 1));
+
+ /* Get the inversed value, clear bits that don't belong to the run */
+ InvValue = ~(*Buffer--) << BitPos >> BitPos;
+
+ /* Skip all set ULONGs */
+ while (InvValue == 0)
+ {
+ /* Did we already reach past the first ULONG? */
+ if (Buffer < BitMapHeader->Buffer)
+ {
+ /* Yes, nothing found */
+ return 0;
+ }
+
+ InvValue = ~(*Buffer--);
+ }
+
+ /* We hit a clear bit, check how many set bits are left */
+ BitScanReverse(&BitPos, InvValue);
+
+ /* Calculate last bit position */
+ FromIndex = (BITMAP_INDEX)((Buffer + 1 - BitMapHeader->Buffer) * _BITCOUNT + BitPos);
+
+ Value = ~InvValue << ((_BITCOUNT - 1) - BitPos) >> ((_BITCOUNT - 1) - BitPos);
+
+ /* Skip all clear ULONGs */
+ while (Value == 0 && Buffer >= BitMapHeader->Buffer)
+ {
+ Value = *Buffer--;
+ }
+
+ if (Value != 0)
+ {
+ /* We hit a set bit, check how many clear bits are left */
+ BitScanReverse(&BitPos, Value);
+
+ /* Calculate Starting Index */
+ *StartingRunIndex = (BITMAP_INDEX)((Buffer + 1 - BitMapHeader->Buffer) * _BITCOUNT + BitPos + 1);
+ }
+ else
+ {
+ /* We reached the start of the bitmap */
+ *StartingRunIndex = 0;
+ }
+
+ /* Return length of the run */
+ return (FromIndex - *StartingRunIndex);
}