[Bug 7833] MS Money 2006 trial aborts on startup, as it calls the unimplemented function shlwapi.dll.SHSetTimerQueueTimer

Wine Bugs wine-bugs at winehq.org
Sat May 19 03:35:20 CDT 2007


http://bugs.winehq.org/show_bug.cgi?id=7833





------- Additional Comments From focht at gmx.net  2007-19-05 03:35 -------
Hello,

yes that would be sufficient due to CreateTimerQueueTimer() returning TRUE all
the time for now.
In case of a real implementation it should of course honour the return value :-)

Just some thoughts about timer queues to whoever wants to take on this API.
For the rest ... skip it, if it becomes a boring read :-)

---
Don't try to implement the timer queues in ADVAPI32

There exist NTDLL API which exposes same functionality.
To avoid code duplication, implement the functionality in NTDLL and let ADVAPI32
just wrap the calls.
Do NT_STATUS to last error conversions in each call, e.g. BaseSetLastNTError(
Status )

Some likely forwards:

CreateTimerQueue() -> RtlCreateTimerQueue()

---

CreateTimerQueueTimer() -> RtlCreateTimer()
If input timer queue handle is NULL, create default timer queue for the process.

---

ChangeTimerQueueTimer() -> RtlUpdateTimer()

If input timer queue handle is NULL, use default timer queue for the process
(if not created yet, return error).

---

DeleteTimerQueueTimer() -> RtlDeleteTimer()

If input timer queue handle is NULL, use default timer queue for the process
(if not created yet, return error).
Generally: take care of CompletionEvent, it is an errornous condition if the
call is synchronous (CompletionEvent == NULL, blocking) and ntdll API returned
STATUS_PENDING!

---

DeleteTimerQueueEx() -> RtlDeleteTimerQueueEx()

=====

Well, there exist some "obsoleted" API which have no ability to specify caller
completion events.

SetTimerQueueTimer() -> RtlCreateTimer()

Should be same like CreateTimerQueueTimer(), optionally forward work to
CreateTimerQueueTimer() with NULL completion event

DeleteTimerQueue() -> RtlDeleteTimerQueueEx()

Should be same like DeleteTimerQueue(), optionally forward work to
DeleteTimerQueue() with NULL completion event.

DeleteTimerQueueTimer() -> RtlDeleteTimer()

--- 

When creating a default timer queue for process, beware of race conditions
(multiple threads call api).
Guards creation/init with appropriate locking mechanisms (atomic).
Create the default queue using RtlCreateTimerQueue, store the handle internally
(in ADVAPI32 module).
This handle is used later whenever client passed in NULL handle, specifying
default queue.

Thoughts about implemention in NTDLL...

The timers in queue should actually be kept as "delta list", where the shot-time
of each timer is relative to timer before it.
Same goes to queues itself (remember the client can create multiple qeues).

Use a system timer to manage all queues and their containing timers.
Service the timer callbacks from a thread (optionally pooled).

It is a good idea to store some information like calling thread id, process id
into queue structure/data.
This would help debugging multithreaded problems a lot.

Forward "old" APIs with no completion events to their respective Ex() functions
with NULL wait event.

Take care of completion events that can be specified in most Ex() functions.
There are 3 cases:

1. The caller passed -1. An event is internally created and waited for
completion of all callbacks.
2. The caller passed NULL (non-blocking function)
   The queue operation is signaled (mark it with some state whatever),
   but the function does not wait for all callbacks to complete (return
STATUS_PENDING)
3. Caller supplied event. The queue operation is signaled (mark it with some
state whatever),
   but the function does not wait for all callbacks to complete.
   After all callbacks are completed, the event is signalled.

One way to service the queue management calls to timer thread(s) would be the
use of APCs.

That's all for now ...
Do not underestimate that stuff.
A robust implementation is not that easy :-)

Regards

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.



More information about the wine-bugs mailing list