https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cf955094b47aaf8aa18e1…
commit cf955094b47aaf8aa18e108825ae59fb919ced24
Author: Tomáš Veselý <turican0(a)gmail.com>
AuthorDate: Tue Oct 22 17:10:34 2024 +0200
Commit: GitHub <noreply(a)github.com>
CommitDate: Tue Oct 22 18:10:34 2024 +0300
[NTUSER] IntSetTimer(): Use timer IDs range [256,32767] as on Windows (#7277)
Based on the Doug Lyons' test in #7087, I found that my previous fix stopped
working partially. Or rather, it would only work until the 32767 indexes were exhausted.
It seems to me that the behavior of the bitfield has changed, because when I published the
previous patch, it passed my tests.
- Bit array generates free ID cyclically, in the previous code after 32767 indexes
expired the same index was returned, because of this the previous fix would stop working
after expiration, so change the logic of calculating the next index.
- Change the index range to 256-32767 to match Windows, indexes 0-255 can
theoretically be used as reserved for system purposes.
Addendum to fd327db20ff. CORE-9141
---
win32ss/user/ntuser/timer.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/win32ss/user/ntuser/timer.c b/win32ss/user/ntuser/timer.c
index db029cc039d..051cf07cc1e 100644
--- a/win32ss/user/ntuser/timer.c
+++ b/win32ss/user/ntuser/timer.c
@@ -17,7 +17,9 @@ static LIST_ENTRY TimersListHead;
static LONG TimeLast = 0;
/* Windows 2000 has room for 32768 window-less timers */
-#define NUM_WINDOW_LESS_TIMERS 32768
+/* These values give timer IDs [256,32767], same as on Windows */
+#define MAX_WINDOW_LESS_TIMER_ID (32768 - 1)
+#define NUM_WINDOW_LESS_TIMERS (32768 - 256)
#define HINTINDEX_BEGIN_VALUE 0
@@ -78,11 +80,12 @@ RemoveTimer(PTIMER pTmr)
RemoveEntryList(&pTmr->ptmrList);
if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM))) //
System timers are reusable.
{
- UINT_PTR IDEvent;
+ ULONG ulBitmapIndex;
- IDEvent = NUM_WINDOW_LESS_TIMERS - pTmr->nID;
+ ASSERT(pTmr->nID <= MAX_WINDOW_LESS_TIMER_ID);
+ ulBitmapIndex = (ULONG)(MAX_WINDOW_LESS_TIMER_ID - pTmr->nID);
IntLockWindowlessTimerBitmap();
- RtlClearBit(&WindowLessTimersBitMap, IDEvent);
+ RtlClearBit(&WindowLessTimersBitMap, ulBitmapIndex);
IntUnlockWindowlessTimerBitmap();
}
UserDereferenceObject(pTmr);
@@ -222,12 +225,8 @@ IntSetTimer( PWND Window,
{
IntLockWindowlessTimerBitmap();
- ulBitmapIndex = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1,
HintIndex++);
- if (ulBitmapIndex == ULONG_MAX)
- {
- HintIndex = HINTINDEX_BEGIN_VALUE;
- ulBitmapIndex = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1,
HintIndex++);
- }
+ ulBitmapIndex = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1,
HintIndex);
+ HintIndex = (ulBitmapIndex + 1) % NUM_WINDOW_LESS_TIMERS;
if (ulBitmapIndex == ULONG_MAX)
{
IntUnlockWindowlessTimerBitmap();
@@ -237,7 +236,7 @@ IntSetTimer( PWND Window,
}
ASSERT(ulBitmapIndex < NUM_WINDOW_LESS_TIMERS);
- IDEvent = NUM_WINDOW_LESS_TIMERS - ulBitmapIndex;
+ IDEvent = MAX_WINDOW_LESS_TIMER_ID - ulBitmapIndex;
Ret = IDEvent;
IntUnlockWindowlessTimerBitmap();