From 65edacf93484faf1dc3d11e555081d69556ccbc3 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 4 Jun 2020 21:21:33 +0200 Subject: [PATCH] ntdll: Move the timer functions to the Unix library. Signed-off-by: Alexandre Julliard --- dlls/ntdll/sync.c | 160 +++------------------------------------ dlls/ntdll/unix/loader.c | 5 ++ dlls/ntdll/unix/sync.c | 149 ++++++++++++++++++++++++++++++++++++ dlls/ntdll/unixlib.h | 12 ++- 4 files changed, 177 insertions(+), 149 deletions(-) diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index bf3539966f6..3b5c4447add 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -647,33 +647,10 @@ NTSTATUS WINAPI NtAssignProcessToJobObject( HANDLE job, HANDLE process ) * NtCreateTimer [NTDLL.@] * ZwCreateTimer [NTDLL.@] */ -NTSTATUS WINAPI NtCreateTimer(OUT HANDLE *handle, - IN ACCESS_MASK access, - IN const OBJECT_ATTRIBUTES *attr OPTIONAL, - IN TIMER_TYPE timer_type) +NTSTATUS WINAPI NtCreateTimer( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, + TIMER_TYPE type ) { - NTSTATUS status; - data_size_t len; - struct object_attributes *objattr; - - if (timer_type != NotificationTimer && timer_type != SynchronizationTimer) - return STATUS_INVALID_PARAMETER; - - if ((status = alloc_object_attributes( attr, &objattr, &len ))) return status; - - SERVER_START_REQ( create_timer ) - { - req->access = access; - req->manual = (timer_type == NotificationTimer); - wine_server_add_data( req, objattr, len ); - status = wine_server_call( req ); - *handle = wine_server_ptr_handle( reply->handle ); - } - SERVER_END_REQ; - - RtlFreeHeap( GetProcessHeap(), 0, objattr ); - return status; - + return unix_funcs->NtCreateTimer( handle, access, attr, type ); } /************************************************************************** @@ -682,148 +659,35 @@ NTSTATUS WINAPI NtCreateTimer(OUT HANDLE *handle, */ NTSTATUS WINAPI NtOpenTimer( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { - NTSTATUS status; - - if ((status = validate_open_object_attributes( attr ))) return status; - - SERVER_START_REQ( open_timer ) - { - req->access = access; - req->attributes = attr->Attributes; - req->rootdir = wine_server_obj_handle( attr->RootDirectory ); - if (attr->ObjectName) - wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); - status = wine_server_call( req ); - *handle = wine_server_ptr_handle( reply->handle ); - } - SERVER_END_REQ; - return status; + return unix_funcs->NtOpenTimer( handle, access, attr ); } /************************************************************************** * NtSetTimer [NTDLL.@] * ZwSetTimer [NTDLL.@] */ -NTSTATUS WINAPI NtSetTimer(IN HANDLE handle, - IN const LARGE_INTEGER* when, - IN PTIMER_APC_ROUTINE callback, - IN PVOID callback_arg, - IN BOOLEAN resume, - IN ULONG period OPTIONAL, - OUT PBOOLEAN state OPTIONAL) +NTSTATUS WINAPI NtSetTimer( HANDLE handle, const LARGE_INTEGER *when, PTIMER_APC_ROUTINE callback, + void *arg, BOOLEAN resume, ULONG period, BOOLEAN *state ) { - NTSTATUS status = STATUS_SUCCESS; - - TRACE("(%p,%p,%p,%p,%08x,0x%08x,%p)\n", - handle, when, callback, callback_arg, resume, period, state); - - SERVER_START_REQ( set_timer ) - { - req->handle = wine_server_obj_handle( handle ); - req->period = period; - req->expire = when->QuadPart; - req->callback = wine_server_client_ptr( callback ); - req->arg = wine_server_client_ptr( callback_arg ); - status = wine_server_call( req ); - if (state) *state = reply->signaled; - } - SERVER_END_REQ; - - /* set error but can still succeed */ - if (resume && status == STATUS_SUCCESS) return STATUS_TIMER_RESUME_IGNORED; - return status; + return unix_funcs->NtSetTimer( handle, when, callback, arg, resume, period, state ); } /************************************************************************** * NtCancelTimer [NTDLL.@] * ZwCancelTimer [NTDLL.@] */ -NTSTATUS WINAPI NtCancelTimer(IN HANDLE handle, OUT BOOLEAN* state) +NTSTATUS WINAPI NtCancelTimer( HANDLE handle, BOOLEAN *state ) { - NTSTATUS status; - - SERVER_START_REQ( cancel_timer ) - { - req->handle = wine_server_obj_handle( handle ); - status = wine_server_call( req ); - if (state) *state = reply->signaled; - } - SERVER_END_REQ; - return status; + return unix_funcs->NtCancelTimer( handle, state ); } /****************************************************************************** * NtQueryTimer (NTDLL.@) - * - * Retrieves information about a timer. - * - * PARAMS - * TimerHandle [I] The timer to retrieve information about. - * TimerInformationClass [I] The type of information to retrieve. - * TimerInformation [O] Pointer to buffer to store information in. - * Length [I] The length of the buffer pointed to by TimerInformation. - * ReturnLength [O] Optional. The size of buffer actually used. - * - * RETURNS - * Success: STATUS_SUCCESS - * Failure: STATUS_INFO_LENGTH_MISMATCH, if Length doesn't match the required data - * size for the class specified. - * STATUS_INVALID_INFO_CLASS, if an invalid TimerInformationClass was specified. - * STATUS_ACCESS_DENIED, if TimerHandle does not have TIMER_QUERY_STATE access - * to the timer. */ -NTSTATUS WINAPI NtQueryTimer( - HANDLE TimerHandle, - TIMER_INFORMATION_CLASS TimerInformationClass, - PVOID TimerInformation, - ULONG Length, - PULONG ReturnLength) +NTSTATUS WINAPI NtQueryTimer( HANDLE handle, TIMER_INFORMATION_CLASS class, + void *info, ULONG len, ULONG *ret_len ) { - TIMER_BASIC_INFORMATION * basic_info = TimerInformation; - NTSTATUS status; - LARGE_INTEGER now; - - TRACE("(%p,%d,%p,0x%08x,%p)\n", TimerHandle, TimerInformationClass, - TimerInformation, Length, ReturnLength); - - switch (TimerInformationClass) - { - case TimerBasicInformation: - if (Length < sizeof(TIMER_BASIC_INFORMATION)) - return STATUS_INFO_LENGTH_MISMATCH; - - SERVER_START_REQ(get_timer_info) - { - req->handle = wine_server_obj_handle( TimerHandle ); - status = wine_server_call(req); - - /* convert server time to absolute NTDLL time */ - basic_info->RemainingTime.QuadPart = reply->when; - basic_info->TimerState = reply->signaled; - } - SERVER_END_REQ; - - /* convert into relative time */ - if (basic_info->RemainingTime.QuadPart > 0) - NtQuerySystemTime(&now); - else - { - RtlQueryPerformanceCounter(&now); - basic_info->RemainingTime.QuadPart = -basic_info->RemainingTime.QuadPart; - } - - if (now.QuadPart > basic_info->RemainingTime.QuadPart) - basic_info->RemainingTime.QuadPart = 0; - else - basic_info->RemainingTime.QuadPart -= now.QuadPart; - - if (ReturnLength) *ReturnLength = sizeof(TIMER_BASIC_INFORMATION); - - return status; - } - - FIXME("Unhandled class %d\n", TimerInformationClass); - return STATUS_INVALID_INFO_CLASS; + return unix_funcs->NtQueryTimer( handle, class, info, len, ret_len ); } diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 9541b1929cc..9041e3fa6d0 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -985,11 +985,13 @@ static struct unix_funcs unix_funcs = { NtAllocateVirtualMemory, NtAreMappedFilesTheSame, + NtCancelTimer, NtClearEvent, NtClose, NtCreateEvent, NtCreateMutant, NtCreateSemaphore, + NtCreateTimer, NtCurrentTeb, NtDelayExecution, NtDuplicateObject, @@ -1002,12 +1004,14 @@ static struct unix_funcs unix_funcs = NtOpenEvent, NtOpenMutant, NtOpenSemaphore, + NtOpenTimer, NtProtectVirtualMemory, NtPulseEvent, NtQueryEvent, NtQueryMutant, NtQuerySection, NtQuerySemaphore, + NtQueryTimer, NtQueryVirtualMemory, NtReadVirtualMemory, NtReleaseMutant, @@ -1017,6 +1021,7 @@ static struct unix_funcs unix_funcs = NtSetContextThread, NtSetEvent, NtSetLdtEntries, + NtSetTimer, NtSignalAndWaitForSingleObject, NtUnlockVirtualMemory, NtUnmapViewOfSection, diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 3d389be44f5..c4753888625 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -532,6 +532,155 @@ NTSTATUS WINAPI NtQueryMutant( HANDLE handle, MUTANT_INFORMATION_CLASS class, } +/************************************************************************** + * NtCreateTimer (NTDLL.@) + */ +NTSTATUS WINAPI NtCreateTimer( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, + TIMER_TYPE type ) +{ + NTSTATUS ret; + data_size_t len; + struct object_attributes *objattr; + + if (type != NotificationTimer && type != SynchronizationTimer) return STATUS_INVALID_PARAMETER; + + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; + + SERVER_START_REQ( create_timer ) + { + req->access = access; + req->manual = (type == NotificationTimer); + wine_server_add_data( req, objattr, len ); + ret = wine_server_call( req ); + *handle = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + + RtlFreeHeap( GetProcessHeap(), 0, objattr ); + return ret; + +} + + +/************************************************************************** + * NtOpenTimer (NTDLL.@) + */ +NTSTATUS WINAPI NtOpenTimer( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) +{ + NTSTATUS ret; + + if ((ret = validate_open_object_attributes( attr ))) return ret; + + SERVER_START_REQ( open_timer ) + { + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); + ret = wine_server_call( req ); + *handle = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + return ret; +} + + +/************************************************************************** + * NtSetTimer (NTDLL.@) + */ +NTSTATUS WINAPI NtSetTimer( HANDLE handle, const LARGE_INTEGER *when, PTIMER_APC_ROUTINE callback, + void *arg, BOOLEAN resume, ULONG period, BOOLEAN *state ) +{ + NTSTATUS ret = STATUS_SUCCESS; + + TRACE( "(%p,%p,%p,%p,%08x,0x%08x,%p)\n", handle, when, callback, arg, resume, period, state ); + + SERVER_START_REQ( set_timer ) + { + req->handle = wine_server_obj_handle( handle ); + req->period = period; + req->expire = when->QuadPart; + req->callback = wine_server_client_ptr( callback ); + req->arg = wine_server_client_ptr( arg ); + ret = wine_server_call( req ); + if (state) *state = reply->signaled; + } + SERVER_END_REQ; + + /* set error but can still succeed */ + if (resume && ret == STATUS_SUCCESS) return STATUS_TIMER_RESUME_IGNORED; + return ret; +} + + +/************************************************************************** + * NtCancelTimer (NTDLL.@) + */ +NTSTATUS WINAPI NtCancelTimer( HANDLE handle, BOOLEAN *state ) +{ + NTSTATUS ret; + + SERVER_START_REQ( cancel_timer ) + { + req->handle = wine_server_obj_handle( handle ); + ret = wine_server_call( req ); + if (state) *state = reply->signaled; + } + SERVER_END_REQ; + return ret; +} + + +/****************************************************************************** + * NtQueryTimer (NTDLL.@) + */ +NTSTATUS WINAPI NtQueryTimer( HANDLE handle, TIMER_INFORMATION_CLASS class, + void *info, ULONG len, ULONG *ret_len ) +{ + TIMER_BASIC_INFORMATION *basic_info = info; + NTSTATUS ret; + LARGE_INTEGER now; + + TRACE( "(%p,%d,%p,0x%08x,%p)\n", handle, class, info, len, ret_len ); + + switch (class) + { + case TimerBasicInformation: + if (len < sizeof(TIMER_BASIC_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH; + + SERVER_START_REQ( get_timer_info ) + { + req->handle = wine_server_obj_handle( handle ); + ret = wine_server_call(req); + /* convert server time to absolute NTDLL time */ + basic_info->RemainingTime.QuadPart = reply->when; + basic_info->TimerState = reply->signaled; + } + SERVER_END_REQ; + + /* convert into relative time */ + if (basic_info->RemainingTime.QuadPart > 0) NtQuerySystemTime( &now ); + else + { + RtlQueryPerformanceCounter( &now ); + basic_info->RemainingTime.QuadPart = -basic_info->RemainingTime.QuadPart; + } + + if (now.QuadPart > basic_info->RemainingTime.QuadPart) + basic_info->RemainingTime.QuadPart = 0; + else + basic_info->RemainingTime.QuadPart -= now.QuadPart; + + if (ret_len) *ret_len = sizeof(TIMER_BASIC_INFORMATION); + return ret; + } + + FIXME( "Unhandled class %d\n", class ); + return STATUS_INVALID_INFO_CLASS; +} + + /****************************************************************** * NtWaitForMultipleObjects (NTDLL.@) */ diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h index 6512cdfcbe5..1eefccc6f0f 100644 --- a/dlls/ntdll/unixlib.h +++ b/dlls/ntdll/unixlib.h @@ -28,7 +28,7 @@ struct ldt_copy; struct msghdr; /* increment this when you change the function table */ -#define NTDLL_UNIXLIB_VERSION 24 +#define NTDLL_UNIXLIB_VERSION 25 struct unix_funcs { @@ -36,6 +36,7 @@ struct unix_funcs NTSTATUS (WINAPI *NtAllocateVirtualMemory)( HANDLE process, PVOID *ret, ULONG_PTR zero_bits, SIZE_T *size_ptr, ULONG type, ULONG protect ); NTSTATUS (WINAPI *NtAreMappedFilesTheSame)(PVOID addr1, PVOID addr2); + NTSTATUS (WINAPI *NtCancelTimer)( HANDLE handle, BOOLEAN *state ); NTSTATUS (WINAPI *NtClearEvent)( HANDLE handle ); NTSTATUS (WINAPI *NtClose)( HANDLE handle ); NTSTATUS (WINAPI *NtCreateEvent)( HANDLE *handle, ACCESS_MASK access, @@ -44,6 +45,8 @@ struct unix_funcs const OBJECT_ATTRIBUTES *attr, BOOLEAN owned ); NTSTATUS (WINAPI *NtCreateSemaphore)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max ); + NTSTATUS (WINAPI *NtCreateTimer)( HANDLE *handle, ACCESS_MASK access, + const OBJECT_ATTRIBUTES *attr, TIMER_TYPE type ); TEB * (WINAPI *NtCurrentTeb)(void); NTSTATUS (WINAPI *NtDelayExecution)( BOOLEAN alertable, const LARGE_INTEGER *timeout ); NTSTATUS (WINAPI *NtDuplicateObject)( HANDLE source_process, HANDLE source, @@ -67,6 +70,8 @@ struct unix_funcs const OBJECT_ATTRIBUTES *attr ); NTSTATUS (WINAPI *NtOpenSemaphore)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ); + NTSTATUS (WINAPI *NtOpenTimer)( HANDLE *handle, ACCESS_MASK access, + const OBJECT_ATTRIBUTES *attr ); NTSTATUS (WINAPI *NtProtectVirtualMemory)( HANDLE process, PVOID *addr_ptr, SIZE_T *size_ptr, ULONG new_prot, ULONG *old_prot ); NTSTATUS (WINAPI *NtPulseEvent)( HANDLE handle, LONG *prev_state ); @@ -78,6 +83,8 @@ struct unix_funcs void *ptr, SIZE_T size, SIZE_T *ret_size ); NTSTATUS (WINAPI *NtQuerySemaphore)( HANDLE handle, SEMAPHORE_INFORMATION_CLASS class, void *info, ULONG len, ULONG *ret_len ); + NTSTATUS (WINAPI *NtQueryTimer)( HANDLE handle, TIMER_INFORMATION_CLASS class, + void *info, ULONG len, ULONG *ret_len ); NTSTATUS (WINAPI *NtQueryVirtualMemory)( HANDLE process, LPCVOID addr, MEMORY_INFORMATION_CLASS info_class, PVOID buffer, SIZE_T len, SIZE_T *res_len ); @@ -90,6 +97,9 @@ struct unix_funcs NTSTATUS (WINAPI *NtSetContextThread)( HANDLE handle, const CONTEXT *context ); NTSTATUS (WINAPI *NtSetEvent)( HANDLE handle, LONG *prev_state ); NTSTATUS (WINAPI *NtSetLdtEntries)( ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_ENTRY entry2 ); + NTSTATUS (WINAPI *NtSetTimer)( HANDLE handle, const LARGE_INTEGER *when, + PTIMER_APC_ROUTINE callback, void *arg, + BOOLEAN resume, ULONG period, BOOLEAN *state ); NTSTATUS (WINAPI *NtSignalAndWaitForSingleObject)( HANDLE signal, HANDLE wait, BOOLEAN alertable, const LARGE_INTEGER *timeout ); NTSTATUS (WINAPI *NtUnlockVirtualMemory)( HANDLE process, PVOID *addr,