diff --git a/sdk/xtdk/rtlfuncs.h b/sdk/xtdk/rtlfuncs.h index 71d6b0c..cbeb95a 100644 --- a/sdk/xtdk/rtlfuncs.h +++ b/sdk/xtdk/rtlfuncs.h @@ -58,6 +58,12 @@ VOID RtlClearBit(IN PRTL_BITMAP BitMap, IN ULONG_PTR Bit); +XTAPI +VOID +RtlClearBits(IN PRTL_BITMAP BitMap, + IN ULONG StartingIndex, + IN ULONG Length); + XTAPI BOOLEAN RtlCompareGuids(IN PGUID Guid1, @@ -185,6 +191,12 @@ VOID RtlSetBit(IN PRTL_BITMAP BitMap, IN ULONG_PTR Bit); +XTAPI +VOID +RtlSetBits(IN PRTL_BITMAP BitMap, + IN ULONG StartingIndex, + IN ULONG Length); + XTAPI VOID RtlSetMemory(OUT PVOID Destination, diff --git a/xtoskrnl/rtl/bitmap.c b/xtoskrnl/rtl/bitmap.c index a78d1e3..15d777c 100644 --- a/xtoskrnl/rtl/bitmap.c +++ b/xtoskrnl/rtl/bitmap.c @@ -56,6 +56,80 @@ RtlClearBit(IN PRTL_BITMAP BitMap, BitMap->Buffer[Bit / BITS_PER_LONG] &= ~(1 << (Bit & (BITS_PER_LONG - 1))); } +/** + * Clears a specified set of bits within a bit map. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param StartingIndex + * Supplies the starting index of the first bit to clear. + * + * @param Length + * Supplies the length (number of bits) to clear. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTAPI +VOID +RtlClearBits(IN PRTL_BITMAP BitMap, + IN ULONG StartingIndex, + IN ULONG Length) +{ + ULONG_PTR BitOffset, Mask; + PULONG_PTR Buffer; + + /* Make sure there is anything to clear */ + if(!Length) + { + /* No bits to clear */ + return; + } + + /* Get pointer to first byte to clear and calculate bit offset */ + Buffer = &BitMap->Buffer[StartingIndex / BITS_PER_LONG]; + BitOffset = StartingIndex & (BITS_PER_LONG - 1); + + /* Check if bit offset is not zero */ + if(BitOffset) + { + /* Get mask and calculate new bit offset */ + Mask = MAXULONG_PTR << BitOffset; + BitOffset = BITS_PER_LONG - BitOffset; + + /* Check if there are enough bits to clear */ + if(Length < BitOffset) + { + /* Recalculate bit offset and fixup the mask */ + BitOffset -= Length; + Mask = Mask << BitOffset >> BitOffset; + + /* Clear bits and return */ + *Buffer &= ~Mask; + return; + } + + /* Clear bits, recalculate length and advance buffer pointer */ + *Buffer &= ~Mask; + Length -= BitOffset; + Buffer++; + } + + /* Clear remaining bits */ + RtlSetMemory(Buffer, 0, Length >> 3); + + /* Look for any remaining bits to clear */ + Buffer += Length / BITS_PER_LONG; + Length &= BITS_PER_LONG - 1; + if(Length) + { + /* Clear what's left */ + *Buffer &= MAXULONG_PTR << Length; + } +} + /** * Dumps the contents of the bit map. * @@ -156,6 +230,80 @@ RtlSetBit(IN PRTL_BITMAP BitMap, BitMap->Buffer[Bit / BITS_PER_LONG] |= 1 << (Bit & (BITS_PER_LONG - 1)); } +/** + * Sets a specified set of bits within a bit map. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param StartingIndex + * Supplies the starting index of the first bit to set. + * + * @param Length + * Supplies the length (number of bits) to set. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTAPI +VOID +RtlSetBits(IN PRTL_BITMAP BitMap, + IN ULONG StartingIndex, + IN ULONG Length) +{ + ULONG_PTR BitOffset, Mask; + PULONG_PTR Buffer; + + /* Make sure there is anything to set */ + if(!Length) + { + /* No bits to set */ + return; + } + + /* Get pointer to first byte to clear and calculate bit offset */ + Buffer = &BitMap->Buffer[StartingIndex / BITS_PER_LONG]; + BitOffset = StartingIndex & (BITS_PER_LONG - 1); + + /* Check if bit offset is not zero */ + if(BitOffset) + { + /* Get mask and calculate new bit offset */ + Mask = MAXULONG_PTR << BitOffset; + BitOffset = BITS_PER_LONG - BitOffset; + + /* Check if there are enough bits to set */ + if(Length < BitOffset) + { + /* Recalculate bit offset and fixup the mask */ + BitOffset -= Length; + Mask = Mask << BitOffset >> BitOffset; + + /* Set bits and return */ + *Buffer |= Mask; + return; + } + + /* Set bits, recalculate length and advance buffer pointer */ + *Buffer |= Mask; + Buffer++; + Length -= BitOffset; + } + + /* Set remaining bits */ + RtlSetMemory(Buffer, 0xFF, Length >> 3); + + /* Look for any remaining bits to set */ + Buffer += Length / BITS_PER_LONG; + Length &= BITS_PER_LONG - 1; + if(Length) + { + /* Set what's left */ + *Buffer |= ~(MAXULONG_PTR << Length); + } +} + /** * Tests a state of a single bit in the bit map. * diff --git a/xtoskrnl/xtoskrnl.spec b/xtoskrnl/xtoskrnl.spec index ea70d9c..d7c55aa 100644 --- a/xtoskrnl/xtoskrnl.spec +++ b/xtoskrnl/xtoskrnl.spec @@ -32,6 +32,7 @@ @ stdcall KeSignalCallDpcSynchronize(ptr) @ stdcall RtlClearAllBits(ptr) @ stdcall RtlClearBit(ptr long) +@ stdcall RtlClearBits(ptr long long) @ stdcall RtlCompareGuids(ptr ptr) @ stdcall RtlCompareMemory(ptr ptr long) @ stdcall RtlCompareString(str str long) @@ -57,6 +58,7 @@ @ stdcall RtlSameMemory(ptr ptr long) @ stdcall RtlSetAllBits(ptr) @ stdcall RtlSetBit(ptr long) +@ stdcall RtlSetBits(ptr long long) @ stdcall RtlSetMemory(ptr long long) @ stdcall RtlStringLength(str long) @ stdcall RtlStringToWideString(wstr str long)