https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cf955094b47aaf8aa18e108825ae59fb919ced24

commit cf955094b47aaf8aa18e108825ae59fb919ced24
Author:     Tomáš Veselý <turic...@gmail.com>
AuthorDate: Tue Oct 22 17:10:34 2024 +0200
Commit:     GitHub <nore...@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();

Reply via email to