[NTUSER] Fix a 64 bit bug in timer code

The return value of RtlFindClearBitsAndSet is an ULONG, assigning it to an ULONG_PTR will not sign extend it. The error value will stay 0xFFFFFFFF. Comparing it to (UINT_PTR)-1 will sign extend and thus compare it to 0xFFFFFFFFFFFFFFFF on x64.
Also use NUM_WINDOW_LESS_TIMERS to initialize the bitmap, rather than the calculated size. This does not make a difference with the current value (32768), but if it was not the case, the bitmap would be larger than this, resulting in invalid bitmap indices being returned, which would cause bugs later on. Finally remove an ASSERT that can be triggered by tests.
This commit is contained in:
Timo Kreuzer 2024-08-29 10:29:38 +03:00
parent 8351fbf04f
commit b385fc5985

View file

@ -183,7 +183,8 @@ IntSetTimer( PWND Window,
INT Type) INT Type)
{ {
PTIMER pTmr; PTIMER pTmr;
UINT Ret = IDEvent; UINT_PTR Ret = IDEvent;
ULONG ulBitmapIndex;
LARGE_INTEGER DueTime; LARGE_INTEGER DueTime;
DueTime.QuadPart = (LONGLONG)(-97656); // 1024hz .9765625 ms set to 10.0 ms DueTime.QuadPart = (LONGLONG)(-97656); // 1024hz .9765625 ms set to 10.0 ms
@ -221,22 +222,22 @@ IntSetTimer( PWND Window,
{ {
IntLockWindowlessTimerBitmap(); IntLockWindowlessTimerBitmap();
IDEvent = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1, HintIndex++); ulBitmapIndex = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1, HintIndex++);
if (IDEvent == (UINT_PTR)-1) if (ulBitmapIndex == ULONG_MAX)
{ {
HintIndex = HINTINDEX_BEGIN_VALUE; HintIndex = HINTINDEX_BEGIN_VALUE;
IDEvent = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1, HintIndex++); ulBitmapIndex = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1, HintIndex++);
} }
if (IDEvent == (UINT_PTR) -1) if (ulBitmapIndex == ULONG_MAX)
{ {
IntUnlockWindowlessTimerBitmap(); IntUnlockWindowlessTimerBitmap();
ERR("Unable to find a free window-less timer id\n"); ERR("Unable to find a free window-less timer id\n");
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES); EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
ASSERT(FALSE);
return 0; return 0;
} }
IDEvent = NUM_WINDOW_LESS_TIMERS - IDEvent; ASSERT(ulBitmapIndex < NUM_WINDOW_LESS_TIMERS);
IDEvent = NUM_WINDOW_LESS_TIMERS - ulBitmapIndex;
Ret = IDEvent; Ret = IDEvent;
IntUnlockWindowlessTimerBitmap(); IntUnlockWindowlessTimerBitmap();
@ -619,7 +620,7 @@ InitTimerImpl(VOID)
RtlInitializeBitMap(&WindowLessTimersBitMap, RtlInitializeBitMap(&WindowLessTimersBitMap,
WindowLessTimersBitMapBuffer, WindowLessTimersBitMapBuffer,
BitmapBytes * 8); NUM_WINDOW_LESS_TIMERS);
/* Yes we need this, since ExAllocatePoolWithTag isn't supposed to zero out allocated memory */ /* Yes we need this, since ExAllocatePoolWithTag isn't supposed to zero out allocated memory */
RtlClearAllBits(&WindowLessTimersBitMap); RtlClearAllBits(&WindowLessTimersBitMap);