Commit 20a1ca2b authored by Dan Hipschman's avatar Dan Hipschman Committed by Alexandre Julliard

ntdll: Implement [Rtl]Create/DeleteTimerQueue[Ex].

parent 09f4ca64
...@@ -1047,9 +1047,16 @@ BOOL WINAPI CancelWaitableTimer( HANDLE handle ) ...@@ -1047,9 +1047,16 @@ BOOL WINAPI CancelWaitableTimer( HANDLE handle )
*/ */
HANDLE WINAPI CreateTimerQueue(void) HANDLE WINAPI CreateTimerQueue(void)
{ {
FIXME("stub\n"); HANDLE q;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); NTSTATUS status = RtlCreateTimerQueue(&q);
return NULL;
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError(status) );
return NULL;
}
return q;
} }
...@@ -1058,9 +1065,15 @@ HANDLE WINAPI CreateTimerQueue(void) ...@@ -1058,9 +1065,15 @@ HANDLE WINAPI CreateTimerQueue(void)
*/ */
BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent) BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
{ {
FIXME("(%p, %p): stub\n", TimerQueue, CompletionEvent); NTSTATUS status = RtlDeleteTimerQueueEx(TimerQueue, CompletionEvent);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0; if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
} }
/*********************************************************************** /***********************************************************************
......
...@@ -605,18 +605,15 @@ static void test_timer_queue(void) ...@@ -605,18 +605,15 @@ static void test_timer_queue(void)
/* Test asynchronous deletion of the queue. */ /* Test asynchronous deletion of the queue. */
q = pCreateTimerQueue(); q = pCreateTimerQueue();
todo_wine
ok(q != NULL, "CreateTimerQueue\n"); ok(q != NULL, "CreateTimerQueue\n");
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pDeleteTimerQueueEx(q, NULL); ret = pDeleteTimerQueueEx(q, NULL);
ok(!ret, "DeleteTimerQueueEx\n"); ok(!ret, "DeleteTimerQueueEx\n");
todo_wine
ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n"); ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
/* Test synchronous deletion of the queue and running timers. */ /* Test synchronous deletion of the queue and running timers. */
q = pCreateTimerQueue(); q = pCreateTimerQueue();
todo_wine
ok(q != NULL, "CreateTimerQueue\n"); ok(q != NULL, "CreateTimerQueue\n");
/* Called once. */ /* Called once. */
...@@ -668,9 +665,9 @@ static void test_timer_queue(void) ...@@ -668,9 +665,9 @@ static void test_timer_queue(void)
Sleep(500); Sleep(500);
ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE); ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
ok(ret, "DeleteTimerQueueEx\n");
todo_wine todo_wine
{ {
ok(ret, "DeleteTimerQueueEx\n");
ok(n1 == 1, "Timer callback 1\n"); ok(n1 == 1, "Timer callback 1\n");
ok(n2 < n3, "Timer callback 2 should be much slower than 3\n"); ok(n2 < n3, "Timer callback 2 should be much slower than 3\n");
} }
...@@ -687,23 +684,18 @@ static void test_timer_queue(void) ...@@ -687,23 +684,18 @@ static void test_timer_queue(void)
} }
q = pCreateTimerQueue(); q = pCreateTimerQueue();
todo_wine
ok(q != NULL, "CreateTimerQueue\n"); ok(q != NULL, "CreateTimerQueue\n");
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pDeleteTimerQueueEx(q, e); ret = pDeleteTimerQueueEx(q, e);
ok(!ret, "DeleteTimerQueueEx\n"); ok(!ret, "DeleteTimerQueueEx\n");
todo_wine
{
ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n"); ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0, ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
"Timer destruction event not triggered\n"); "Timer destruction event not triggered\n");
}
CloseHandle(e); CloseHandle(e);
/* Test deleting/changing a timer in execution. */ /* Test deleting/changing a timer in execution. */
q = pCreateTimerQueue(); q = pCreateTimerQueue();
todo_wine
ok(q != NULL, "CreateTimerQueue\n"); ok(q != NULL, "CreateTimerQueue\n");
d2.t = t2 = NULL; d2.t = t2 = NULL;
...@@ -731,9 +723,9 @@ static void test_timer_queue(void) ...@@ -731,9 +723,9 @@ static void test_timer_queue(void)
Sleep(200); Sleep(200);
ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE); ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
ok(ret, "DeleteTimerQueueEx\n");
todo_wine todo_wine
{ {
ok(ret, "DeleteTimerQueueEx\n");
ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n"); ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n"); ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
} }
......
...@@ -489,7 +489,7 @@ ...@@ -489,7 +489,7 @@
# @ stub RtlCreateSystemVolumeInformationFolder # @ stub RtlCreateSystemVolumeInformationFolder
@ stub RtlCreateTagHeap @ stub RtlCreateTagHeap
# @ stub RtlCreateTimer # @ stub RtlCreateTimer
# @ stub RtlCreateTimerQueue @ stdcall RtlCreateTimerQueue(ptr)
@ stdcall RtlCreateUnicodeString(ptr wstr) @ stdcall RtlCreateUnicodeString(ptr wstr)
@ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str) @ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str)
@ stub RtlCreateUserProcess @ stub RtlCreateUserProcess
...@@ -520,7 +520,7 @@ ...@@ -520,7 +520,7 @@
@ stdcall RtlDeleteSecurityObject(ptr) @ stdcall RtlDeleteSecurityObject(ptr)
# @ stub RtlDeleteTimer # @ stub RtlDeleteTimer
# @ stub RtlDeleteTimerQueue # @ stub RtlDeleteTimerQueue
# @ stub RtlDeleteTimerQueueEx @ stdcall RtlDeleteTimerQueueEx(ptr ptr)
@ stdcall RtlDeregisterWait(ptr) @ stdcall RtlDeregisterWait(ptr)
@ stdcall RtlDeregisterWaitEx(ptr ptr) @ stdcall RtlDeregisterWaitEx(ptr ptr)
@ stdcall RtlDestroyAtomTable(ptr) @ stdcall RtlDestroyAtomTable(ptr)
......
...@@ -528,3 +528,75 @@ NTSTATUS WINAPI RtlDeregisterWait(HANDLE WaitHandle) ...@@ -528,3 +528,75 @@ NTSTATUS WINAPI RtlDeregisterWait(HANDLE WaitHandle)
{ {
return RtlDeregisterWaitEx(WaitHandle, NULL); return RtlDeregisterWaitEx(WaitHandle, NULL);
} }
/************************** Timer Queue Impl **************************/
struct queue_timer
{
struct list entry;
};
struct timer_queue
{
RTL_CRITICAL_SECTION cs;
struct list timers;
};
/***********************************************************************
* RtlCreateTimerQueue (NTDLL.@)
*
* Creates a timer queue object and returns a handle to it.
*
* PARAMS
* NewTimerQueue [O] The newly created queue.
*
* RETURNS
* Success: STATUS_SUCCESS.
* Failure: Any NTSTATUS code.
*/
NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue)
{
struct timer_queue *q = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *q);
if (!q)
return STATUS_NO_MEMORY;
RtlInitializeCriticalSection(&q->cs);
list_init(&q->timers);
*NewTimerQueue = q;
return STATUS_SUCCESS;
}
/***********************************************************************
* RtlDeleteTimerQueueEx (NTDLL.@)
*
* Deletes a timer queue object.
*
* PARAMS
* TimerQueue [I] The timer queue to destroy.
* CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE,
* wait until all timers are finished firing before
* returning. Otherwise, return immediately and set the
* event when all timers are done.
*
* RETURNS
* Success: STATUS_SUCCESS if synchronous, STATUS_PENDING if not.
* Failure: Any NTSTATUS code.
*/
NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
{
struct timer_queue *q = TimerQueue;
RtlDeleteCriticalSection(&q->cs);
RtlFreeHeap(GetProcessHeap(), 0, q);
if (CompletionEvent == INVALID_HANDLE_VALUE)
return STATUS_SUCCESS;
else
{
if (CompletionEvent)
NtSetEvent(CompletionEvent, NULL);
return STATUS_PENDING;
}
}
...@@ -2117,6 +2117,7 @@ NTSYSAPI NTSTATUS WINAPI RtlCreateEnvironment(BOOLEAN, PWSTR*); ...@@ -2117,6 +2117,7 @@ NTSYSAPI NTSTATUS WINAPI RtlCreateEnvironment(BOOLEAN, PWSTR*);
NTSYSAPI HANDLE WINAPI RtlCreateHeap(ULONG,PVOID,SIZE_T,SIZE_T,PVOID,PRTL_HEAP_DEFINITION); NTSYSAPI HANDLE WINAPI RtlCreateHeap(ULONG,PVOID,SIZE_T,SIZE_T,PVOID,PRTL_HEAP_DEFINITION);
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 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*);
...@@ -2127,6 +2128,7 @@ NTSYSAPI NTSTATUS WINAPI RtlDeleteCriticalSection(RTL_CRITICAL_SECTION *); ...@@ -2127,6 +2128,7 @@ NTSYSAPI NTSTATUS WINAPI RtlDeleteCriticalSection(RTL_CRITICAL_SECTION *);
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR); NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR);
NTSYSAPI void WINAPI RtlDeleteResource(LPRTL_RWLOCK); NTSYSAPI void WINAPI RtlDeleteResource(LPRTL_RWLOCK);
NTSYSAPI NTSTATUS WINAPI RtlDeleteSecurityObject(PSECURITY_DESCRIPTOR*); NTSYSAPI NTSTATUS WINAPI RtlDeleteSecurityObject(PSECURITY_DESCRIPTOR*);
NTSYSAPI NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE, HANDLE);
NTSYSAPI PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams(RTL_USER_PROCESS_PARAMETERS*); NTSYSAPI PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams(RTL_USER_PROCESS_PARAMETERS*);
NTSYSAPI NTSTATUS WINAPI RtlDeregisterWait(HANDLE); NTSYSAPI NTSTATUS WINAPI RtlDeregisterWait(HANDLE);
NTSYSAPI NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE,HANDLE); NTSYSAPI NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE,HANDLE);
......
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