From e2eb8c169753aa89e197f1445daa8f23c5f6e4dd Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 8 Mar 2000 01:55:34 +0000 Subject: [PATCH] Added more bitmap functions Fixed some STDCALL issues svn path=/trunk/; revision=1035 --- reactos/include/ddk/rtl.h | 107 +++++- reactos/include/internal/service.h | 18 + reactos/ntoskrnl/ke/i386/usercall.c | 8 +- reactos/ntoskrnl/ntoskrnl.def | 40 +- reactos/ntoskrnl/ntoskrnl.edf | 27 +- reactos/ntoskrnl/rtl/bitmap.c | 564 +++++++++++++++++++++++++++- 6 files changed, 703 insertions(+), 61 deletions(-) diff --git a/reactos/include/ddk/rtl.h b/reactos/include/ddk/rtl.h index 667efadf532..97e8a6905a6 100644 --- a/reactos/include/ddk/rtl.h +++ b/reactos/include/ddk/rtl.h @@ -1,4 +1,4 @@ -/* $Id: rtl.h,v 1.28 2000/03/03 00:38:15 ekohl Exp $ +/* $Id: rtl.h,v 1.29 2000/03/08 01:52:52 ekohl Exp $ * */ @@ -262,6 +262,22 @@ RtlAppendUnicodeToString ( PWSTR Source ); +BOOLEAN +STDCALL +RtlAreBitsClear ( + PRTL_BITMAP BitMapHeader, + ULONG StartingIndex, + ULONG Length + ); + +BOOLEAN +STDCALL +RtlAreBitsSet ( + PRTL_BITMAP BitMapHeader, + ULONG StartingIndex, + ULONG Length + ); + NTSTATUS STDCALL RtlCharToInteger ( @@ -499,6 +515,66 @@ RtlFillMemoryUlong ( ULONG Fill ); +ULONG +STDCALL +RtlFindClearBits ( + PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex + ); + +ULONG +STDCALL +RtlFindClearBitsAndSet ( + PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex + ); + +ULONG +STDCALL +RtlFindFirstRunClear ( + PRTL_BITMAP BitMapHeader, + PULONG StartingIndex + ); + +ULONG +STDCALL +RtlFindFirstRunSet ( + PRTL_BITMAP BitMapHeader, + PULONG StartingIndex + ); + +ULONG +STDCALL +RtlFindLongestRunClear ( + PRTL_BITMAP BitMapHeader, + PULONG StartingIndex + ); + +ULONG +STDCALL +RtlFindLongestRunSet ( + PRTL_BITMAP BitMapHeader, + PULONG StartingIndex + ); + +ULONG +STDCALL +RtlFindSetBits ( + PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex + ); + +ULONG +STDCALL +RtlFindSetBitsAndClear ( + PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex + ); + VOID STDCALL RtlFreeAnsiString ( @@ -839,6 +915,18 @@ RtlNtStatusToPsxErrno ( NTSTATUS StatusCode ); +ULONG +STDCALL +RtlNumberOfClearBits ( + PRTL_BITMAP BitMapHeader + ); + +ULONG +STDCALL +RtlNumberOfSetBits ( + PRTL_BITMAP BitMapHeader + ); + ULONG STDCALL RtlOemStringToUnicodeSize ( @@ -914,6 +1002,14 @@ RtlSetAllBits ( IN PRTL_BITMAP BitMapHeader ); +VOID +STDCALL +RtlSetBits ( + PRTL_BITMAP BitMapHeader, + ULONG StartingIndex, + ULONG NumberToSet + ); + NTSTATUS STDCALL RtlSetDaclSecurityDescriptor ( @@ -931,15 +1027,6 @@ RtlSizeHeap ( PVOID pmem ); -#if 0 -PWSTR -RtlStrtok ( - PUNICODE_STRING _string, - PWSTR _sep, - PWSTR * temp - ); -#endif - VOID RtlStoreLong ( PULONG Address, diff --git a/reactos/include/internal/service.h b/reactos/include/internal/service.h index f75b73afd47..99ea1254401 100644 --- a/reactos/include/internal/service.h +++ b/reactos/include/internal/service.h @@ -29,7 +29,25 @@ typedef struct t_KeServiceDescriptorTableEntry { #pragma pack() + +/* --- NTOSKRNL.EXE --- */ +#if defined(__NTOSKRNL__) +extern +KE_SERVICE_DESCRIPTOR_TABLE_ENTRY +KeServiceDescriptorTable[SSDT_MAX_ENTRIES] __declspec(dllexport); +#else +extern +KE_SERVICE_DESCRIPTOR_TABLE_ENTRY +KeServiceDescriptorTable[SSDT_MAX_ENTRIES] __declspec(dllimport); +#endif + +extern +KE_SERVICE_DESCRIPTOR_TABLE_ENTRY +KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES]; + + BOOLEAN +STDCALL KeAddSystemServiceTable ( PSSDT SSDT, PULONG ServiceCounterTable, diff --git a/reactos/ntoskrnl/ke/i386/usercall.c b/reactos/ntoskrnl/ke/i386/usercall.c index a9a1334cbeb..16febe5ff56 100644 --- a/reactos/ntoskrnl/ke/i386/usercall.c +++ b/reactos/ntoskrnl/ke/i386/usercall.c @@ -1,4 +1,4 @@ -/* $Id: usercall.c,v 1.9 2000/02/25 00:33:30 ekohl Exp $ +/* $Id: usercall.c,v 1.10 2000/03/08 01:53:59 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -22,9 +22,6 @@ #include -extern KE_SERVICE_DESCRIPTOR_TABLE_ENTRY KeServiceDescriptorTable[]; -extern KE_SERVICE_DESCRIPTOR_TABLE_ENTRY KeServiceDescriptorTableShadow[]; - #define _STR(x) #x #define STR(x) _STR(x) @@ -92,6 +89,7 @@ ULONG KiAfterSystemCallHook(ULONG NtStatus, PCONTEXT Context) // TableIndex is 0 based // ServiceCountTable its not used at the moment BOOLEAN +STDCALL KeAddSystemServiceTable ( PSSDT SSDT, PULONG ServiceCounterTable, @@ -285,3 +283,5 @@ void interrupt_handler2e(void); "popl %ebp\n\t" /* Ebp */ "iret\n\t"); + +/* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index a9cd2cb26be..d9401f44638 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.def,v 1.53 2000/03/06 01:02:30 ea Exp $ +; $Id: ntoskrnl.def,v 1.54 2000/03/08 01:55:34 ekohl Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -187,7 +187,7 @@ IofCompleteRequest@8 KdDebuggerEnabled DATA KdDebuggerNotPresent DATA KdPollBreakIn@0 -KeAddSystemServiceTable +KeAddSystemServiceTable@20 KeBugCheck KeBugCheckEx KeClearEvent @@ -203,17 +203,18 @@ KeInsertQueueDpc KeQuerySystemTime KeReadStateEvent KeResetEvent +KeServiceDescriptorTable DATA KeSetEvent KeSetTimer KeSynchronizeExecution KeWaitForSingleObject MmGetSystemAddressForMdl MmMapIoSpace -NlsAnsiCodePage DATA -NlsLeadByteInfo DATA -NlsMbCodePageTag DATA -NlsMbOemCodePageTag DATA -NlsOemLeadByteInfo DATA +NlsAnsiCodePage DATA +NlsLeadByteInfo DATA +NlsMbCodePageTag DATA +NlsMbOemCodePageTag DATA +NlsOemLeadByteInfo DATA NtAddAtom@8 NtAdjustPrivilegesToken@24 NtAllocateLocallyUniqueId@4 @@ -287,8 +288,8 @@ RtlAppendUnicodeStringToString@8 RtlAppendUnicodeToString@8 ;RtlAreAllAccessesGranted ;RtlAreAnyAccessesGranted -;RtlAreBitsClear -;RtlAreBitsSet +RtlAreBitsClear@12 +RtlAreBitsSet@12 ;RtlAssert ;RtlCaptureStackBackTrace RtlCharToInteger@12 @@ -342,15 +343,15 @@ RtlExtendedLargeIntegerDivide@16 RtlExtendedMagicDivide@20 RtlFillMemory@12 RtlFillMemoryUlong@12 -;RtlFindClearBits -;RtlFindClearBitsAndSet -;RtlFindFirstRunClear -;RtlFindFirstRunSet -;RtlFindLongestRunClear -;RtlFindLongestRunSet +RtlFindClearBits@12 +RtlFindClearBitsAndSet@12 +RtlFindFirstRunClear@8 +RtlFindFirstRunSet@8 +RtlFindLongestRunClear@8 +RtlFindLongestRunSet@8 ;RtlFindMessage -;RtlFindSetBits -;RtlFindSetBitsAndClear +RtlFindSetBits@12 +RtlFindSetBitsAndClear@12 ;RtlFindUnicodePrefix ;RtlFormatCurrentUserKeyPath RtlFreeAnsiString@4 @@ -399,8 +400,8 @@ RtlMultiByteToUnicodeSize@12 ;RtlNtStatusToDosError ;RtlNtStatusToDosErrorNoTeb ;RtlNumberGenericTableElements -;RtlNumberOfClearBits -;RtlNumberOfSetBits +RtlNumberOfClearBits@4 +RtlNumberOfSetBits@4 RtlOemStringToCountedUnicodeString@12 RtlOemStringToUnicodeSize@4 RtlOemStringToUnicodeString@12 @@ -721,4 +722,3 @@ WRITE_PORT_ULONG@8 WRITE_PORT_USHORT@8 InsertTailList RemoveEntryList -_KeServiceDescriptorTable DATA diff --git a/reactos/ntoskrnl/ntoskrnl.edf b/reactos/ntoskrnl/ntoskrnl.edf index a857e33444c..4cca77bc280 100644 --- a/reactos/ntoskrnl/ntoskrnl.edf +++ b/reactos/ntoskrnl/ntoskrnl.edf @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.edf,v 1.40 2000/03/06 01:02:30 ea Exp $ +; $Id: ntoskrnl.edf,v 1.41 2000/03/08 01:55:34 ekohl Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -187,7 +187,7 @@ IofCompleteRequest=IofCompleteRequest@8 KdDebuggerEnabled DATA KdDebuggerNotPresent DATA KdPollBreakIn=KdPollBreakIn@0 -KeAddSystemServiceTable +KeAddSystemServiceTable=KeAddSystemServiceTable@20 KeBugCheck KeBugCheckEx KeClearEvent @@ -203,17 +203,18 @@ KeInsertQueueDpc KeQuerySystemTime KeReadStateEvent KeResetEvent +KeServiceDescriptorTable DATA KeSetEvent KeSetTimer KeSynchronizeExecution KeWaitForSingleObject MmGetSystemAddressForMdl MmMapIoSpace -NlsAnsiCodePage DATA -NlsLeadByteInfo DATA -NlsMbCodePageTag DATA -NlsMbOemCodePageTag DATA -NlsOemLeadByteInfo DATA +NlsAnsiCodePage DATA +NlsLeadByteInfo DATA +NlsMbCodePageTag DATA +NlsMbOemCodePageTag DATA +NlsOemLeadByteInfo DATA NtAddAtom=NtAddAtom@8 NtAdjustPrivilegesToken=NtAdjustPrivilegesToken@24 NtAllocateLocallyUniqueId=NtAllocateLocallyUniqueId@4 @@ -280,6 +281,8 @@ RtlAppendAsciizToString=RtlAppendAsciizToString@8 RtlAppendStringToString=RtlAppendStringToString@8 RtlAppendUnicodeStringToString=RtlAppendUnicodeStringToString@8 RtlAppendUnicodeToString=RtlAppendUnicodeToString@8 +RtlAreBitsClear=RtlAreBitsClear@12 +RtlAreBitsSet=RtlAreBitsSet@12 RtlCharToInteger=RtlCharToInteger@12 RtlClearAllBits=RtlClearAllBits@4 RtlClearBits=RtlClearBits@12 @@ -308,6 +311,14 @@ RtlExtendedLargeIntegerDivide=RtlExtendedLargeIntegerDivide@16 RtlExtendedMagicDivide=RtlExtendedMagicDivide@20 RtlFillMemory=RtlFillMemory@12 RtlFillMemoryUlong=RtlFillMemoryUlong@12 +RtlFindClearBits=RtlFindClearBits@12 +RtlFindClearBitsAndSet=RtlFindClearBitsAndSet@12 +RtlFindFirstRunClear=RtlFindFirstRunClear@8 +RtlFindFirstRunSet=RtlFindFirstRunSet@8 +RtlFindLongestRunClear=RtlFindLongestRunClear@8 +RtlFindLongestRunSet=RtlFindLongestRunSet@8 +RtlFindSetBits=RtlFindSetBits@12 +RtlFindSetBitsAndClear=RtlFindSetBitsAndClear@12 RtlFreeAnsiString=RtlFreeAnsiString@4 RtlFreeOemString=RtlFreeOemString@4 RtlFreeUnicodeString=RtlFreeUnicodeString@4 @@ -335,6 +346,8 @@ RtlLengthSid=RtlLengthSid@4 RtlMoveMemory=RtlMoveMemory@12 RtlMultiByteToUnicodeN=RtlMultiByteToUnicodeN@20 RtlMultiByteToUnicodeSize=RtlMultiByteToUnicodeSize@12 +RtlNumberOfClearBits=RtlNumberOfClearBits@4 +RtlNumberOfSetBits=RtlNumberOfSetBits@4 RtlOemStringToCountedUnicodeString=RtlOemStringToCountedUnicodeString@12 RtlOemStringToUnicodeSize=RtlOemStringToUnicodeSize@4 RtlOemStringToUnicodeString=RtlOemStringToUnicodeString@12 diff --git a/reactos/ntoskrnl/rtl/bitmap.c b/reactos/ntoskrnl/rtl/bitmap.c index f832aa400d0..1dce92777ef 100644 --- a/reactos/ntoskrnl/rtl/bitmap.c +++ b/reactos/ntoskrnl/rtl/bitmap.c @@ -1,4 +1,4 @@ -/* $Id: bitmap.c,v 1.1 2000/03/03 00:48:50 ekohl Exp $ +/* $Id: bitmap.c,v 1.2 2000/03/08 01:54:34 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -27,6 +27,84 @@ RtlInitializeBitMap ( } +BOOLEAN +STDCALL +RtlAreBitsClear ( + PRTL_BITMAP BitMapHeader, + ULONG StartingIndex, + ULONG Length + ) +{ + ULONG Size = BitMapHeader->SizeOfBitMap; + ULONG Shift; + ULONG Count; + PCHAR Ptr; + + if (StartingIndex >= Size || + !Length || + (StartingIndex + Length > Size)) + return FALSE; + + Ptr = (PCHAR)BitMapHeader->Buffer + (StartingIndex / 8); + while (Length) + { + /* get bit shift in current byte */ + Shift = StartingIndex & 7; + + /* get number of bits to check in current byte */ + Count = (Length > 8 - Shift) ? 8 - Shift : Length; + + /* check byte */ + if (*Ptr++ & (~(0xFF << Count) << Shift)) + return FALSE; + + Length -= Count; + StartingIndex += Count; + } + + return TRUE; +} + + +BOOLEAN +STDCALL +RtlAreBitsSet ( + PRTL_BITMAP BitMapHeader, + ULONG StartingIndex, + ULONG Length + ) +{ + ULONG Size = BitMapHeader->SizeOfBitMap; + ULONG Shift; + ULONG Count; + PCHAR Ptr; + + if (StartingIndex >= Size || + !Length || + (StartingIndex + Length > Size)) + return FALSE; + + Ptr = (PCHAR)BitMapHeader->Buffer + (StartingIndex / 8); + while (Length) + { + /* get bit shift in current byte */ + Shift = StartingIndex & 7; + + /* get number of bits to check in current byte */ + Count = (Length > 8 - Shift) ? 8 - Shift : Length; + + /* check byte */ + if (~*Ptr++ & (~(0xFF << Count) << Shift)) + return FALSE; + + Length -= Count; + StartingIndex += Count; + } + + return TRUE; +} + + VOID STDCALL RtlClearAllBits ( @@ -48,9 +126,9 @@ RtlClearBits ( ) { ULONG Size = BitMapHeader->SizeOfBitMap; - ULONG n; - ULONG shift; - PCHAR p; + ULONG Count; + ULONG Shift; + PCHAR Ptr; if (StartingIndex >= Size || NumberToClear == 0) return; @@ -58,23 +136,469 @@ RtlClearBits ( if (StartingIndex + NumberToClear > Size) NumberToClear = Size - StartingIndex; - p = (PCHAR)(BitMapHeader->Buffer + (StartingIndex / 8)); + Ptr = (PCHAR)(BitMapHeader->Buffer + (StartingIndex / 8)); while (NumberToClear) { /* bit shift in current byte */ - shift = StartingIndex & 7; + Shift = StartingIndex & 7; /* number of bits to change in current byte */ - n = (NumberToClear > 8 - shift ) ? 8 - shift : NumberToClear; + Count = (NumberToClear > 8 - Shift ) ? 8 - Shift : NumberToClear; /* adjust byte */ - *p++ &= ~(~(0xFF << n) << shift); - NumberToClear -= n; - StartingIndex += n; + *Ptr++ &= ~(~(0xFF << Count) << Shift); + NumberToClear -= Count; + StartingIndex += Count; } } +ULONG +STDCALL +RtlFindClearBits ( + PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex + ) +{ + ULONG Size = BitMapHeader->SizeOfBitMap; + ULONG Index; + ULONG Count; + PCHAR Ptr; + CHAR Mask; + + if (NumberToFind > Size || NumberToFind == 0) + return -1; + + if (HintIndex >= Size) + HintIndex = 0; + + Index = HintIndex; + Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8); + Mask = 1 << (Index & 7); + + while (HintIndex < Size) + { + /* count clear bits */ + for (Count = 0; Index < Size && ~*Ptr & Mask; Index++) + { + if (++Count >= NumberToFind) + return HintIndex; + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + /* skip set bits */ + for (; Index < Size && *Ptr & Mask; Index++) + { + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + HintIndex = Index; + } + + return -1; +} + + +ULONG +STDCALL +RtlFindClearBitsAndSet ( + PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex + ) +{ + ULONG Index; + + Index = RtlFindClearBits (BitMapHeader, + NumberToFind, + HintIndex); + if (Index != (ULONG)-1) + RtlSetBits (BitMapHeader, + Index, + NumberToFind); + + return Index; +} + + +ULONG +STDCALL +RtlFindFirstRunClear ( + PRTL_BITMAP BitMapHeader, + PULONG StartingIndex + ) +{ + ULONG Size = BitMapHeader->SizeOfBitMap; + ULONG Index; + ULONG Count; + PCHAR Ptr; + CHAR Mask; + + if (*StartingIndex > Size) + { + *StartingIndex = (ULONG)-1; + return 0; + } + + Index = *StartingIndex; + Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8); + Mask = 1 << (Index & 7); + + /* skip set bits */ + for (; Index < Size && *Ptr & Mask; Index++) + { + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + /* return index of first clear bit */ + if (Index >= Size) + { + *StartingIndex = (ULONG)-1; + return 0; + } + else + *StartingIndex = Index; + + /* count clear bits */ + for (Count = 0; Index < Size && ~*Ptr & Mask; Index++) + { + Count++; + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + return Count; +} + + +ULONG +STDCALL +RtlFindFirstRunSet ( + PRTL_BITMAP BitMapHeader, + PULONG StartingIndex + ) +{ + ULONG Size = BitMapHeader->SizeOfBitMap; + ULONG Index; + ULONG Count; + PCHAR Ptr; + CHAR Mask; + + if (*StartingIndex > Size) + { + *StartingIndex = (ULONG)-1; + return 0; + } + + Index = *StartingIndex; + Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8); + Mask = 1 << (Index & 7); + + /* skip clear bits */ + for (; Index < Size && ~*Ptr & Mask; Index++) + { + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + /* return index of first set bit */ + if (Index >= Size) + { + *StartingIndex = (ULONG)-1; + return 0; + } + else + *StartingIndex = Index; + + /* count set bits */ + for (Count = 0; Index < Size && *Ptr & Mask; Index++) + { + Count++; + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + return Count; +} + + +ULONG +STDCALL +RtlFindLongestRunClear ( + PRTL_BITMAP BitMapHeader, + PULONG StartingIndex + ) +{ + ULONG Size = BitMapHeader->SizeOfBitMap; + PCHAR Ptr = (PCHAR)BitMapHeader->Buffer; + ULONG Index = 0; + ULONG Count; + ULONG Max = 0; + ULONG Start; + ULONG Maxstart = 0; + CHAR Mask = 1; + + while (Index < Size) + { + Start = Index; + + /* count clear bits */ + for (Count = 0; Index < Size && ~*Ptr & Mask; Index++) + { + Count++; + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + /* skip set bits */ + for (; Index < Size && *Ptr & Mask; Index++) + { + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + if (Count > Max) + { + Max = Count; + Maxstart = Start; + } + } + + if (StartingIndex) + *StartingIndex = Maxstart; + + return Max; +} + + +ULONG +STDCALL +RtlFindLongestRunSet ( + PRTL_BITMAP BitMapHeader, + PULONG StartingIndex + ) +{ + ULONG Size = BitMapHeader->SizeOfBitMap; + PCHAR Ptr = (PCHAR)BitMapHeader->Buffer; + ULONG Index = 0; + ULONG Count; + ULONG Max = 0; + ULONG Start; + ULONG Maxstart = 0; + CHAR Mask = 1; + + while (Index < Size) + { + Start = Index; + + /* count set bits */ + for (Count = 0; Index < Size && *Ptr & Mask; Index++) + { + Count++; + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + /* skip clear bits */ + for (; Index < Size && ~*Ptr & Mask; Index++) + { + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + if (Count > Max) + { + Max = Count; + Maxstart = Start; + } + } + + if (StartingIndex) + *StartingIndex = Maxstart; + + return Max; +} + + +ULONG +STDCALL +RtlFindSetBits ( + PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex + ) +{ + ULONG Size = BitMapHeader->SizeOfBitMap; + ULONG Index; + ULONG Count; + PCHAR Ptr; + CHAR Mask; + + if (NumberToFind > Size || NumberToFind == 0) + return (ULONG)-1; + + if (HintIndex >= Size) + HintIndex = 0; + + Index = HintIndex; + Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8); + Mask = 1 << (Index & 7); + + while (HintIndex < Size) + { + /* count set bits */ + for (Count = 0; Index < Size && *Ptr & Mask; Index++) + { + if (++Count >= NumberToFind) + return HintIndex; + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + /* skip clear bits */ + for (; Index < Size && ~*Ptr & Mask; Index++) + { + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + HintIndex = Index; + } + + return (ULONG)-1; +} + + +ULONG +STDCALL +RtlFindSetBitsAndClear ( + PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex + ) +{ + ULONG Index; + + Index = RtlFindSetBits (BitMapHeader, + NumberToFind, + HintIndex); + if (Index != (ULONG)-1) + RtlClearBits (BitMapHeader, + Index, + NumberToFind); + + return Index; +} + + +ULONG +STDCALL +RtlNumberOfClearBits ( + PRTL_BITMAP BitMapHeader + ) +{ + PCHAR Ptr = (PCHAR)BitMapHeader->Buffer; + ULONG Size = BitMapHeader->SizeOfBitMap; + ULONG Index; + ULONG Count; + CHAR Mask; + + for (Mask = 1, Index = 0, Count = 0; Index < Size; Index++) + { + if (~*Ptr & Mask) + Count++; + + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + return Count; +} + + +ULONG +STDCALL +RtlNumberOfSetBits ( + PRTL_BITMAP BitMapHeader + ) +{ + PCHAR Ptr = (PCHAR)BitMapHeader->Buffer; + ULONG Size = BitMapHeader->SizeOfBitMap; + ULONG Index; + ULONG Count; + CHAR Mask; + + for (Mask = 1, Index = 0, Count = 0; Index < Size; Index++) + { + if (*Ptr & Mask) + Count++; + + Mask <<= 1; + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + return Count; +} + + VOID STDCALL RtlSetAllBits ( @@ -86,6 +610,7 @@ RtlSetAllBits ( ALIGN(BitMapHeader->SizeOfBitMap, 8)); } + VOID STDCALL RtlSetBits ( @@ -95,9 +620,9 @@ RtlSetBits ( ) { ULONG Size = BitMapHeader->SizeOfBitMap; - ULONG n; - ULONG shift; - PCHAR p; + ULONG Count; + ULONG Shift; + PCHAR Ptr; if (StartingIndex >= Size || NumberToSet == 0) return; @@ -105,21 +630,20 @@ RtlSetBits ( if (StartingIndex + NumberToSet > Size) NumberToSet = Size - StartingIndex; - p = (PCHAR)BitMapHeader->Buffer + (StartingIndex / 8); + Ptr = (PCHAR)BitMapHeader->Buffer + (StartingIndex / 8); while (NumberToSet) { /* bit shift in current byte */ - shift = StartingIndex & 7; + Shift = StartingIndex & 7; /* number of bits to change in current byte */ - n = (NumberToSet > 8 - shift) ? 8 - shift : NumberToSet; + Count = (NumberToSet > 8 - Shift) ? 8 - Shift : NumberToSet; /* adjust byte */ - *p++ |= ~( 0xFF << n ) << shift; - NumberToSet -= n; - StartingIndex += n; + *Ptr++ |= ~(0xFF << Count) << Shift; + NumberToSet -= Count; + StartingIndex += Count; } } - /* EOF */