http://bugs.winehq.org/show_bug.cgi?id=7833
------- Additional Comments From focht@gmx.net 2007-18-05 18:07 ------- Hello,
sorry but how this supposed to work?
You're passing a bogus pointer into CreateTimerQueueTimer() which is a stub itself.
--- snip dlls/shlwapi/ordinal.c --- HANDLE WINAPI SHSetTimerQueueTimer(HANDLE hQueue, WAITORTIMERCALLBACK pfnCallback, LPVOID pContext, DWORD dwDueTime, DWORD dwPeriod, LPCSTR lpszLibrary, DWORD dwFlags) { HANDLE *phNewTimer;
/* SHSetTimerQueueTimer flags -> CreateTimerQueueTimer flags */ if (dwFlags & TPS_LONGEXECTIME) { dwFlags &= ~TPS_LONGEXECTIME; dwFlags |= WT_EXECUTELONGFUNCTION; } if (dwFlags & TPS_EXECUTEIO) { dwFlags &= ~TPS_EXECUTEIO; dwFlags |= WT_EXECUTEINIOTHREAD; }
CreateTimerQueueTimer(phNewTimer, hQueue, pfnCallback, pContext, dwDueTime, dwPeriod, dwFlags);
return *phNewTimer; } --- snip dlls/shlwapi/ordinal.c ---
The value of phNewTimer is != 0 due the way the compiler generated the stack frame. That bogus value gets returned to client (msmoney code). Client thinks "oh nice, i got a handle, the function must have succeeded, lets go on" (val != 0 -> valid handle for client).
The client executes a loop in main thread, where it does WaitForMultipleObjEx() (waiting on two handles) and optionally pumps messages. One of the handles is actually an event which is (re)set in timer callback. Due to non-existing implementation of the timer queue api, the callback gets never called. The event is never signalled, it loops forever.
So how about:
--- snip --- HANDLE hNewTimer;
...
return CreateTimerQueueTimer( &hNewTimer, ...) ? hNewTimer : NULL; --- snip ---
Which is of course useless yet because as pointed out in my previous comment, the whole timer queue api is missing.
Regards