[1/4] ntdll: Implement RtlCreateTimer for kernel32's CreateTimerQueueTimer.
Dan Hipschman
dsh at linux.ucla.edu
Tue Jul 22 20:10:08 CDT 2008
---
dlls/kernel32/sync.c | 14 +++++++----
dlls/kernel32/tests/sync.c | 7 -----
dlls/ntdll/ntdll.spec | 2 +-
dlls/ntdll/threadpool.c | 57 ++++++++++++++++++++++++++++++++++++++++++++
include/winternl.h | 1 +
5 files changed, 68 insertions(+), 13 deletions(-)
diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c
index 7bce445..c739a5b 100644
--- a/dlls/kernel32/sync.c
+++ b/dlls/kernel32/sync.c
@@ -1085,16 +1085,20 @@ BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
*
* RETURNS
* nonzero on success or zero on failure
- *
- * BUGS
- * Unimplemented
*/
BOOL WINAPI CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue,
WAITORTIMERCALLBACK Callback, PVOID Parameter,
DWORD DueTime, DWORD Period, ULONG Flags )
{
- FIXME("stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ NTSTATUS status = RtlCreateTimer(phNewTimer, TimerQueue, Callback,
+ Parameter, DueTime, Period, Flags);
+
+ if (status != STATUS_SUCCESS)
+ {
+ SetLastError( RtlNtStatusToDosError(status) );
+ return FALSE;
+ }
+
return TRUE;
}
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c
index 697f905..05f67dc 100644
--- a/dlls/kernel32/tests/sync.c
+++ b/dlls/kernel32/tests/sync.c
@@ -622,7 +622,6 @@ static void test_timer_queue(void)
ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
0, 0);
ok(ret, "CreateTimerQueueTimer\n");
- todo_wine
ok(t1 != NULL, "CreateTimerQueueTimer\n");
/* A slow one. */
@@ -631,7 +630,6 @@ static void test_timer_queue(void)
ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
100, 0);
ok(ret, "CreateTimerQueueTimer\n");
- todo_wine
ok(t2 != NULL, "CreateTimerQueueTimer\n");
/* A fast one. */
@@ -640,7 +638,6 @@ static void test_timer_queue(void)
ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
10, 0);
ok(ret, "CreateTimerQueueTimer\n");
- todo_wine
ok(t3 != NULL, "CreateTimerQueueTimer\n");
/* Start really late (it won't start). */
@@ -649,7 +646,6 @@ static void test_timer_queue(void)
ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
10, 0);
ok(ret, "CreateTimerQueueTimer\n");
- todo_wine
ok(t4 != NULL, "CreateTimerQueueTimer\n");
/* Start soon, but delay so long it won't run again. */
@@ -658,7 +654,6 @@ static void test_timer_queue(void)
ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
10000, 0);
ok(ret, "CreateTimerQueueTimer\n");
- todo_wine
ok(t5 != NULL, "CreateTimerQueueTimer\n");
/* Give them a chance to do some work. */
@@ -706,7 +701,6 @@ static void test_timer_queue(void)
10, 0);
d2.t = t2;
ok(ret, "CreateTimerQueueTimer\n");
- todo_wine
ok(t2 != NULL, "CreateTimerQueueTimer\n");
d3.t = t3 = NULL;
@@ -717,7 +711,6 @@ static void test_timer_queue(void)
10, 0);
d3.t = t3;
ok(ret, "CreateTimerQueueTimer\n");
- todo_wine
ok(t3 != NULL, "CreateTimerQueueTimer\n");
Sleep(200);
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 0be408e..595a5f6 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -488,7 +488,7 @@
@ stdcall RtlCreateSecurityDescriptor(ptr long)
# @ stub RtlCreateSystemVolumeInformationFolder
@ stub RtlCreateTagHeap
-# @ stub RtlCreateTimer
+@ stdcall RtlCreateTimer(ptr ptr ptr ptr long long long)
@ stdcall RtlCreateTimerQueue(ptr)
@ stdcall RtlCreateUnicodeString(ptr wstr)
@ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str)
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index aa03959..c698cb7 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -543,6 +543,12 @@ struct timer_queue
struct list timers;
};
+static void queue_remove_timer(struct queue_timer *t)
+{
+ list_remove(&t->entry);
+ RtlFreeHeap(GetProcessHeap(), 0, t);
+}
+
/***********************************************************************
* RtlCreateTimerQueue (NTDLL.@)
*
@@ -587,6 +593,12 @@ NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue)
NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
{
struct timer_queue *q = TimerQueue;
+ struct queue_timer *t, *temp;
+
+ RtlEnterCriticalSection(&q->cs);
+ LIST_FOR_EACH_ENTRY_SAFE(t, temp, &q->timers, struct queue_timer, entry)
+ queue_remove_timer(t);
+ RtlLeaveCriticalSection(&q->cs);
RtlDeleteCriticalSection(&q->cs);
RtlFreeHeap(GetProcessHeap(), 0, q);
@@ -600,3 +612,48 @@ NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
return STATUS_PENDING;
}
}
+
+/***********************************************************************
+ * RtlCreateTimer (NTDLL.@)
+ *
+ * Creates a new timer associated with the given queue.
+ *
+ * PARAMS
+ * NewTimer [O] The newly created timer.
+ * TimerQueue [I] The queue to hold the timer.
+ * Callback [I] The callback to fire.
+ * Parameter [I] The argument for the callback.
+ * DueTime [I] The delay, in milliseconds, before first firing the
+ * timer.
+ * Period [I] The period, in milliseconds, at which to fire the timer
+ * after the first callback. If zero, the timer will only
+ * fire once. It still needs to be deleted with
+ * RtlDeleteTimer.
+ * Flags [I] Flags controling the execution of the callback. In
+ * addition to the WT_* thread pool flags (see
+ * RtlQueueWorkItem), WT_EXECUTEINTIMERTHREAD and
+ * WT_EXECUTEONLYONCE are supported.
+ *
+ * RETURNS
+ * Success: STATUS_SUCCESS.
+ * Failure: Any NTSTATUS code.
+ */
+NTSTATUS WINAPI RtlCreateTimer(PHANDLE NewTimer, HANDLE TimerQueue,
+ RTL_WAITORTIMERCALLBACKFUNC Callback,
+ PVOID Parameter, DWORD DueTime, DWORD Period,
+ ULONG Flags)
+{
+ struct timer_queue *q = TimerQueue;
+ struct queue_timer *t = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *t);
+ if (!t)
+ return STATUS_NO_MEMORY;
+
+ FIXME("timer expiration unimplemented\n");
+
+ RtlEnterCriticalSection(&q->cs);
+ list_add_tail(&q->timers, &t->entry);
+ RtlLeaveCriticalSection(&q->cs);
+
+ *NewTimer = t;
+ return STATUS_SUCCESS;
+}
diff --git a/include/winternl.h b/include/winternl.h
index 7b8e055..30bd0e5 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2118,6 +2118,7 @@ NTSYSAPI HANDLE WINAPI RtlCreateHeap(ULONG,PVOID,SIZE_T,SIZE_T,PVOID,PRTL_HEA
NTSYSAPI NTSTATUS WINAPI RtlCreateProcessParameters(RTL_USER_PROCESS_PARAMETERS**,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*,PWSTR,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*);
NTSYSAPI NTSTATUS WINAPI RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD);
NTSYSAPI NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE);
+NTSYSAPI NTSTATUS WINAPI RtlCreateTimer(PHANDLE, HANDLE, RTL_WAITORTIMERCALLBACKFUNC, PVOID, DWORD, DWORD, ULONG);
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR);
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR);
NTSYSAPI NTSTATUS WINAPI RtlCreateUserThread(HANDLE,const SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*);
More information about the wine-patches
mailing list