Dan Hipschman : ntdll: Implement RtlCreateTimer for kernel32' s CreateTimerQueueTimer.

Alexandre Julliard julliard at winehq.org
Wed Jul 23 07:09:48 CDT 2008


Module: wine
Branch: master
Commit: d343f2baf76413eb690cbc44a0d56ed39915328d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d343f2baf76413eb690cbc44a0d56ed39915328d

Author: Dan Hipschman <dsh at linux.ucla.edu>
Date:   Tue Jul 22 18:10:08 2008 -0700

ntdll: Implement RtlCreateTimer for kernel32's CreateTimerQueueTimer.

---

 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-cvs mailing list