void Test_RtlAreBitsClear(void) { RTL_BITMAP BitMapHeader; ULONG *Buffer; Buffer = AllocateGuarded(2 * sizeof(*Buffer)); RtlInitializeBitMap(&BitMapHeader, Buffer, 19); Buffer[0] = 0x00ff00ff; Buffer[1] = 0xc0cfc0cf; ok_hex(RtlAreBitsClear(&BitMapHeader, 0, 8), FALSE); ok_hex(RtlAreBitsClear(&BitMapHeader, 8, 8), TRUE); ok_hex(RtlAreBitsClear(&BitMapHeader, 7, 8), FALSE); ok_hex(RtlAreBitsClear(&BitMapHeader, 8, 9), FALSE); ok_hex(RtlAreBitsClear(&BitMapHeader, 24, 1), FALSE); RtlInitializeBitMap(&BitMapHeader, Buffer, 31); ok_hex(RtlAreBitsClear(&BitMapHeader, 24, 1), TRUE); ok_hex(RtlAreBitsClear(&BitMapHeader, 24, 7), TRUE); ok_hex(RtlAreBitsClear(&BitMapHeader, 24, 8), FALSE); RtlInitializeBitMap(&BitMapHeader, Buffer, 64); ok_hex(RtlAreBitsClear(&BitMapHeader, 60, 4), FALSE); FreeGuarded(Buffer); }
BOOLEAN AllocatePort( PPORT_SET PortSet, ULONG Port ) { BOOLEAN Clear; KIRQL OldIrql; Port = htons(Port); if ((Port < PortSet->StartingPort) || (Port >= PortSet->StartingPort + PortSet->PortsToOversee)) { return FALSE; } Port -= PortSet->StartingPort; KeAcquireSpinLock( &PortSet->Lock, &OldIrql ); Clear = RtlAreBitsClear( &PortSet->ProtoBitmap, Port, 1 ); if( Clear ) RtlSetBits( &PortSet->ProtoBitmap, Port, 1 ); KeReleaseSpinLock( &PortSet->Lock, OldIrql ); return Clear; }
static UCHAR XmsRealloc(WORD Handle, WORD NewSize) { DWORD BlockNumber; PXMS_HANDLE HandleEntry = GetHandleRecord(Handle); DWORD CurrentIndex = 0; ULONG RunStart; ULONG RunSize; if (!ValidateHandle(HandleEntry)) return XMS_STATUS_INVALID_HANDLE; if (HandleEntry->LockCount) return XMS_STATUS_LOCKED; /* Get the block number */ BlockNumber = (HandleEntry->Address - XMS_ADDRESS) / XMS_BLOCK_SIZE; if (NewSize < HandleEntry->Size) { /* Just reduce the size of this block */ RtlClearBits(&AllocBitmap, BlockNumber + NewSize, HandleEntry->Size - NewSize); FreeBlocks += HandleEntry->Size - NewSize; HandleEntry->Size = NewSize; } else if (NewSize > HandleEntry->Size) { /* Check if we can expand in-place */ if (RtlAreBitsClear(&AllocBitmap, BlockNumber + HandleEntry->Size, NewSize - HandleEntry->Size)) { /* Just increase the size of this block */ RtlSetBits(&AllocBitmap, BlockNumber + HandleEntry->Size, NewSize - HandleEntry->Size); FreeBlocks -= NewSize - HandleEntry->Size; HandleEntry->Size = NewSize; /* We're done */ return XMS_STATUS_SUCCESS; } /* Deallocate the current block range */ RtlClearBits(&AllocBitmap, BlockNumber, HandleEntry->Size); /* Find a new place for this block */ while (CurrentIndex < XMS_BLOCKS) { RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart); if (RunSize == 0) break; if (RunSize >= NewSize) { /* Allocate the new range */ RtlSetBits(&AllocBitmap, RunStart, NewSize); /* Move the data to the new location */ RtlMoveMemory((PVOID)REAL_TO_PHYS(XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE), (PVOID)REAL_TO_PHYS(HandleEntry->Address), HandleEntry->Size * XMS_BLOCK_SIZE); /* Update the handle entry */ HandleEntry->Address = XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE; HandleEntry->Size = NewSize; /* Update the free block counter */ FreeBlocks -= NewSize - HandleEntry->Size; return XMS_STATUS_SUCCESS; } /* Keep searching */ CurrentIndex = RunStart + RunSize; } /* Restore the old block range */ RtlSetBits(&AllocBitmap, BlockNumber, HandleEntry->Size); return XMS_STATUS_OUT_OF_MEMORY; } return XMS_STATUS_SUCCESS; }
BOOL NtdllBitmap::AreBitsClear( ULONG starting_index, ULONG length ) { assert(RtlAreBitsClear != NULL); return RtlAreBitsClear(this, starting_index, length); }