Re: timeSetEvent() wraps after inteval of 429496
- From: "Alexander Grigoriev" <alegr@xxxxxxxxxxxxx>
- Date: Fri, 3 Jun 2005 22:06:05 -0700
Looks like the internal math to convert miliseconds to 100 ns units is using
32 bits. This means anything more that2^32 / 10000 ms gets truncated.
"Chris P." <msdn@xxxxxxxxxxxx> wrote in message
news:q9ca7uqmj1rd$.1v08n1w09vq3u.dlg@xxxxxxxxxxxxx
>
> There is a bug in timeSetEvent(), which is used to schedule a callback
> after a given period, in that if the period is greater than 429496
> milliseconds the actual time period will wrap back to x-429496. So for
> example, setting a period of 430000 which generate a callback in 504ms.
> This is despite the capabilities reported by timeGetDevCaps() reporting
> the
> maximum supported value is 1000000.
>
> The actual exports for these time functions are in winmm.dll, and this bug
> seems to have been there for quite a while. I've tested on XP SP2 back to
> Win2K, but don't have anything older on hand. I don't see how it could be
> used as a security compromise in any way, but the behavior is definately
> unexpected.
>
> Below is complete repro code. Thanks BilalD for reporting this.
>
>
> <code>
>
> // timerbug.cpp
> //
> // This code reproduces a bug in timeSetEvent() where if a periodic timing
> event is set for
> // a interval larger than 429496 milliseconds, a wrap occurs and the
> timing
> interval is
> // actually x-429496 milliseconds. This also occurs at the mulitple,
> 858992 where the
> // result will be x-858992 milliseconds.
> // This bug only effects PERIODIC timers, it does not seem to effect
> ONESHOT timers.
>
> #pragma comment ( lib, "winmm.lib" )
>
> #include "stdafx.h"
> #include <windows.h>
> #include <stdio.h>
> #include <conio.h>
> #include <mmsystem.h>
>
> HANDLE g_timerEvent;
> DWORD g_Start;
>
> #define TIMER_INTERVAL 430000
> #define MILLIPERSEC 1000.0
>
> void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1,
> DWORD
> dw2);
>
> int _tmain(int argc, _TCHAR* argv[])
> {
> printf("Press any key to start timer for %0.3f seconds\n",
> TIMER_INTERVAL/MILLIPERSEC);
> getch();
>
> TIMECAPS caps;
> timeGetDevCaps(&caps, sizeof(TIMECAPS));
> printf("Timer caps min:%i max:%i\n", caps.wPeriodMin, caps.wPeriodMax);
>
> g_timerEvent = CreateEvent(NULL, 0, FALSE, NULL);
> g_Start = GetTickCount();
>
> MMRESULT result = timeSetEvent(TIMER_INTERVAL, 1000, TimerProc, 0,
> TIME_PERIODIC);
> // wait for the timerproc to receive timing event
> WaitForSingleObject(g_timerEvent, INFINITE);
>
> printf("Test complete\n");
> DWORD duration = GetTickCount()-g_Start;
> printf("Our timer lasted for %0.3f seconds\n", duration/MILLIPERSEC);
> int diff = (int)duration - TIMER_INTERVAL;
> diff = abs(diff);
> if (diff > 1000)
> printf("The timer is broken. Expected %0.1fs, got %0.1fs\n",
> TIMER_INTERVAL/MILLIPERSEC, duration/MILLIPERSEC);
> else
> printf("The timer is working OK.\n");
> CloseHandle(g_timerEvent);
> getch();
> return 0;
> }
>
>
> void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1,
> DWORD
> dw2)
> {
> timeKillEvent(uID);
> SetEvent(g_timerEvent);
> }
>
>
> </code>
.
- Follow-Ups:
- Re: timeSetEvent() wraps after inteval of 429496
- From: Chris P. [MVP]
- Re: timeSetEvent() wraps after inteval of 429496
- References:
- BUG: timeSetEvent() wraps after inteval of 429496
- From: Chris P.
- BUG: timeSetEvent() wraps after inteval of 429496
- Prev by Date: Re: can't play wav file snippet
- Next by Date: Re: timeSetEvent() wraps after inteval of 429496
- Previous by thread: BUG: timeSetEvent() wraps after inteval of 429496
- Next by thread: Re: timeSetEvent() wraps after inteval of 429496
- Index(es):
Relevant Pages
|
|