Commit d343f2ba authored by Dan Hipschman's avatar Dan Hipschman Committed by Alexandre Julliard

ntdll: Implement RtlCreateTimer for kernel32's CreateTimerQueueTimer.

parent dab03963
...@@ -1085,16 +1085,20 @@ BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent) ...@@ -1085,16 +1085,20 @@ BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
* *
* RETURNS * RETURNS
* nonzero on success or zero on failure * nonzero on success or zero on failure
*
* BUGS
* Unimplemented
*/ */
BOOL WINAPI CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue, BOOL WINAPI CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue,
WAITORTIMERCALLBACK Callback, PVOID Parameter, WAITORTIMERCALLBACK Callback, PVOID Parameter,
DWORD DueTime, DWORD Period, ULONG Flags ) DWORD DueTime, DWORD Period, ULONG Flags )
{ {
FIXME("stub\n"); NTSTATUS status = RtlCreateTimer(phNewTimer, TimerQueue, Callback,
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); Parameter, DueTime, Period, Flags);
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE; return TRUE;
} }
......
...@@ -622,7 +622,6 @@ static void test_timer_queue(void) ...@@ -622,7 +622,6 @@ static void test_timer_queue(void)
ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0, ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
0, 0); 0, 0);
ok(ret, "CreateTimerQueueTimer\n"); ok(ret, "CreateTimerQueueTimer\n");
todo_wine
ok(t1 != NULL, "CreateTimerQueueTimer\n"); ok(t1 != NULL, "CreateTimerQueueTimer\n");
/* A slow one. */ /* A slow one. */
...@@ -631,7 +630,6 @@ static void test_timer_queue(void) ...@@ -631,7 +630,6 @@ static void test_timer_queue(void)
ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0, ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
100, 0); 100, 0);
ok(ret, "CreateTimerQueueTimer\n"); ok(ret, "CreateTimerQueueTimer\n");
todo_wine
ok(t2 != NULL, "CreateTimerQueueTimer\n"); ok(t2 != NULL, "CreateTimerQueueTimer\n");
/* A fast one. */ /* A fast one. */
...@@ -640,7 +638,6 @@ static void test_timer_queue(void) ...@@ -640,7 +638,6 @@ static void test_timer_queue(void)
ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0, ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
10, 0); 10, 0);
ok(ret, "CreateTimerQueueTimer\n"); ok(ret, "CreateTimerQueueTimer\n");
todo_wine
ok(t3 != NULL, "CreateTimerQueueTimer\n"); ok(t3 != NULL, "CreateTimerQueueTimer\n");
/* Start really late (it won't start). */ /* Start really late (it won't start). */
...@@ -649,7 +646,6 @@ static void test_timer_queue(void) ...@@ -649,7 +646,6 @@ static void test_timer_queue(void)
ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000, ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
10, 0); 10, 0);
ok(ret, "CreateTimerQueueTimer\n"); ok(ret, "CreateTimerQueueTimer\n");
todo_wine
ok(t4 != NULL, "CreateTimerQueueTimer\n"); ok(t4 != NULL, "CreateTimerQueueTimer\n");
/* Start soon, but delay so long it won't run again. */ /* Start soon, but delay so long it won't run again. */
...@@ -658,7 +654,6 @@ static void test_timer_queue(void) ...@@ -658,7 +654,6 @@ static void test_timer_queue(void)
ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0, ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
10000, 0); 10000, 0);
ok(ret, "CreateTimerQueueTimer\n"); ok(ret, "CreateTimerQueueTimer\n");
todo_wine
ok(t5 != NULL, "CreateTimerQueueTimer\n"); ok(t5 != NULL, "CreateTimerQueueTimer\n");
/* Give them a chance to do some work. */ /* Give them a chance to do some work. */
...@@ -706,7 +701,6 @@ static void test_timer_queue(void) ...@@ -706,7 +701,6 @@ static void test_timer_queue(void)
10, 0); 10, 0);
d2.t = t2; d2.t = t2;
ok(ret, "CreateTimerQueueTimer\n"); ok(ret, "CreateTimerQueueTimer\n");
todo_wine
ok(t2 != NULL, "CreateTimerQueueTimer\n"); ok(t2 != NULL, "CreateTimerQueueTimer\n");
d3.t = t3 = NULL; d3.t = t3 = NULL;
...@@ -717,7 +711,6 @@ static void test_timer_queue(void) ...@@ -717,7 +711,6 @@ static void test_timer_queue(void)
10, 0); 10, 0);
d3.t = t3; d3.t = t3;
ok(ret, "CreateTimerQueueTimer\n"); ok(ret, "CreateTimerQueueTimer\n");
todo_wine
ok(t3 != NULL, "CreateTimerQueueTimer\n"); ok(t3 != NULL, "CreateTimerQueueTimer\n");
Sleep(200); Sleep(200);
......
...@@ -488,7 +488,7 @@ ...@@ -488,7 +488,7 @@
@ stdcall RtlCreateSecurityDescriptor(ptr long) @ stdcall RtlCreateSecurityDescriptor(ptr long)
# @ stub RtlCreateSystemVolumeInformationFolder # @ stub RtlCreateSystemVolumeInformationFolder
@ stub RtlCreateTagHeap @ stub RtlCreateTagHeap
# @ stub RtlCreateTimer @ stdcall RtlCreateTimer(ptr ptr ptr ptr long long long)
@ stdcall RtlCreateTimerQueue(ptr) @ stdcall RtlCreateTimerQueue(ptr)
@ stdcall RtlCreateUnicodeString(ptr wstr) @ stdcall RtlCreateUnicodeString(ptr wstr)
@ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str) @ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str)
......
...@@ -543,6 +543,12 @@ struct timer_queue ...@@ -543,6 +543,12 @@ struct timer_queue
struct list timers; struct list timers;
}; };
static void queue_remove_timer(struct queue_timer *t)
{
list_remove(&t->entry);
RtlFreeHeap(GetProcessHeap(), 0, t);
}
/*********************************************************************** /***********************************************************************
* RtlCreateTimerQueue (NTDLL.@) * RtlCreateTimerQueue (NTDLL.@)
* *
...@@ -587,6 +593,12 @@ NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue) ...@@ -587,6 +593,12 @@ NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue)
NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent) NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
{ {
struct timer_queue *q = TimerQueue; 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); RtlDeleteCriticalSection(&q->cs);
RtlFreeHeap(GetProcessHeap(), 0, q); RtlFreeHeap(GetProcessHeap(), 0, q);
...@@ -600,3 +612,48 @@ NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent) ...@@ -600,3 +612,48 @@ NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
return STATUS_PENDING; 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;
}
...@@ -2118,6 +2118,7 @@ NTSYSAPI HANDLE WINAPI RtlCreateHeap(ULONG,PVOID,SIZE_T,SIZE_T,PVOID,PRTL_HEA ...@@ -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 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 RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD);
NTSYSAPI NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE); 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 RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR);
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR); 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*); NTSYSAPI NTSTATUS WINAPI RtlCreateUserThread(HANDLE,const SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment