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

commit b385fc5985cbb658c3062833f59eddaf49f01ec7
Author:     Timo Kreuzer <timo.kreu...@reactos.org>
AuthorDate: Thu Aug 29 10:29:38 2024 +0300
Commit:     Timo Kreuzer <timo.kreu...@reactos.org>
CommitDate: Sun Sep 8 01:52:50 2024 +0300

    [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.
---
 win32ss/user/ntuser/timer.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

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

Reply via email to