Implement NtQueryTimer.
This commit is contained in:
parent
dff8de638c
commit
7572b125b5
@ -187,7 +187,7 @@
|
|||||||
@ stub NtQuerySystemEnvironmentValue
|
@ stub NtQuerySystemEnvironmentValue
|
||||||
@ stdcall NtQuerySystemInformation(long long long long)
|
@ stdcall NtQuerySystemInformation(long long long long)
|
||||||
@ stdcall NtQuerySystemTime(ptr)
|
@ stdcall NtQuerySystemTime(ptr)
|
||||||
@ stub NtQueryTimer
|
@ stdcall NtQueryTimer(ptr long ptr long ptr)
|
||||||
@ stdcall NtQueryTimerResolution(long long long)
|
@ stdcall NtQueryTimerResolution(long long long)
|
||||||
@ stdcall NtQueryValueKey(long long long long long long)
|
@ stdcall NtQueryValueKey(long long long long long long)
|
||||||
@ stdcall NtQueryVirtualMemory(long ptr long ptr long ptr)
|
@ stdcall NtQueryVirtualMemory(long ptr long ptr long ptr)
|
||||||
|
@ -42,6 +42,7 @@ extern LPCSTR debugstr_us( const UNICODE_STRING *str );
|
|||||||
extern void dump_ObjectAttributes (const OBJECT_ATTRIBUTES *ObjectAttributes);
|
extern void dump_ObjectAttributes (const OBJECT_ATTRIBUTES *ObjectAttributes);
|
||||||
|
|
||||||
extern void NTDLL_get_server_timeout( abs_time_t *when, const LARGE_INTEGER *timeout );
|
extern void NTDLL_get_server_timeout( abs_time_t *when, const LARGE_INTEGER *timeout );
|
||||||
|
extern void NTDLL_from_server_timeout( LARGE_INTEGER *timeout, const abs_time_t *when );
|
||||||
extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags,
|
extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags,
|
||||||
const LARGE_INTEGER *timeout );
|
const LARGE_INTEGER *timeout );
|
||||||
|
|
||||||
|
@ -510,6 +510,74 @@ NTSTATUS WINAPI NtCancelTimer(IN HANDLE handle, OUT BOOLEAN* state)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
TIMER_BASIC_INFORMATION * basic_info = (TIMER_BASIC_INFORMATION *)TimerInformation;
|
||||||
|
NTSTATUS status;
|
||||||
|
LARGE_INTEGER now;
|
||||||
|
|
||||||
|
TRACE("(%p,%d,%p,0x%08lx,%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 = TimerHandle;
|
||||||
|
status = wine_server_call(req);
|
||||||
|
|
||||||
|
/* convert server time to absolute NTDLL time */
|
||||||
|
NTDLL_from_server_timeout(&basic_info->RemainingTime, &reply->when);
|
||||||
|
basic_info->TimerState = reply->signaled;
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
|
||||||
|
/* convert from absolute into relative time */
|
||||||
|
NtQuerySystemTime(&now);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* NtQueryTimerResolution [NTDLL.@]
|
* NtQueryTimerResolution [NTDLL.@]
|
||||||
*/
|
*/
|
||||||
|
@ -398,6 +398,18 @@ void NTDLL_get_server_timeout( abs_time_t *when, const LARGE_INTEGER *timeout )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NTDLL_from_server_timeout
|
||||||
|
*
|
||||||
|
* Convert a timeval struct from the server into an NTDLL timeout.
|
||||||
|
*/
|
||||||
|
void NTDLL_from_server_timeout( LARGE_INTEGER *timeout, const abs_time_t *when )
|
||||||
|
{
|
||||||
|
timeout->QuadPart = when->sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
|
||||||
|
timeout->QuadPart += when->usec * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* RtlTimeToTimeFields [NTDLL.@]
|
* RtlTimeToTimeFields [NTDLL.@]
|
||||||
*
|
*
|
||||||
|
@ -1928,6 +1928,19 @@ struct cancel_timer_reply
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct get_timer_info_request
|
||||||
|
{
|
||||||
|
struct request_header __header;
|
||||||
|
obj_handle_t handle;
|
||||||
|
};
|
||||||
|
struct get_timer_info_reply
|
||||||
|
{
|
||||||
|
struct reply_header __header;
|
||||||
|
abs_time_t when;
|
||||||
|
int signaled;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct get_thread_context_request
|
struct get_thread_context_request
|
||||||
{
|
{
|
||||||
@ -3239,6 +3252,7 @@ enum request
|
|||||||
REQ_open_timer,
|
REQ_open_timer,
|
||||||
REQ_set_timer,
|
REQ_set_timer,
|
||||||
REQ_cancel_timer,
|
REQ_cancel_timer,
|
||||||
|
REQ_get_timer_info,
|
||||||
REQ_get_thread_context,
|
REQ_get_thread_context,
|
||||||
REQ_set_thread_context,
|
REQ_set_thread_context,
|
||||||
REQ_get_selector_entry,
|
REQ_get_selector_entry,
|
||||||
@ -3424,6 +3438,7 @@ union generic_request
|
|||||||
struct open_timer_request open_timer_request;
|
struct open_timer_request open_timer_request;
|
||||||
struct set_timer_request set_timer_request;
|
struct set_timer_request set_timer_request;
|
||||||
struct cancel_timer_request cancel_timer_request;
|
struct cancel_timer_request cancel_timer_request;
|
||||||
|
struct get_timer_info_request get_timer_info_request;
|
||||||
struct get_thread_context_request get_thread_context_request;
|
struct get_thread_context_request get_thread_context_request;
|
||||||
struct set_thread_context_request set_thread_context_request;
|
struct set_thread_context_request set_thread_context_request;
|
||||||
struct get_selector_entry_request get_selector_entry_request;
|
struct get_selector_entry_request get_selector_entry_request;
|
||||||
@ -3607,6 +3622,7 @@ union generic_reply
|
|||||||
struct open_timer_reply open_timer_reply;
|
struct open_timer_reply open_timer_reply;
|
||||||
struct set_timer_reply set_timer_reply;
|
struct set_timer_reply set_timer_reply;
|
||||||
struct cancel_timer_reply cancel_timer_reply;
|
struct cancel_timer_reply cancel_timer_reply;
|
||||||
|
struct get_timer_info_reply get_timer_info_reply;
|
||||||
struct get_thread_context_reply get_thread_context_reply;
|
struct get_thread_context_reply get_thread_context_reply;
|
||||||
struct set_thread_context_reply set_thread_context_reply;
|
struct set_thread_context_reply set_thread_context_reply;
|
||||||
struct get_selector_entry_reply get_selector_entry_reply;
|
struct get_selector_entry_reply get_selector_entry_reply;
|
||||||
@ -3681,6 +3697,6 @@ union generic_reply
|
|||||||
struct set_global_windows_reply set_global_windows_reply;
|
struct set_global_windows_reply set_global_windows_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 152
|
#define SERVER_PROTOCOL_VERSION 153
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
@ -632,6 +632,16 @@ typedef struct _MUTANT_BASIC_INFORMATION {
|
|||||||
BOOLEAN AbandonedState;
|
BOOLEAN AbandonedState;
|
||||||
} MUTANT_BASIC_INFORMATION, *PMUTANT_BASIC_INFORMATION;
|
} MUTANT_BASIC_INFORMATION, *PMUTANT_BASIC_INFORMATION;
|
||||||
|
|
||||||
|
typedef enum _TIMER_INFORMATION_CLASS
|
||||||
|
{
|
||||||
|
TimerBasicInformation = 0
|
||||||
|
} TIMER_INFORMATION_CLASS;
|
||||||
|
|
||||||
|
typedef struct _TIMER_BASIC_INFORMATION
|
||||||
|
{
|
||||||
|
LARGE_INTEGER RemainingTime;
|
||||||
|
BOOLEAN TimerState;
|
||||||
|
} TIMER_BASIC_INFORMATION, *PTIMER_BASIC_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
/* return type of RtlDetermineDosPathNameType_U (FIXME: not the correct names) */
|
/* return type of RtlDetermineDosPathNameType_U (FIXME: not the correct names) */
|
||||||
@ -1401,6 +1411,7 @@ NTSTATUS WINAPI NtQueryObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, P
|
|||||||
NTSTATUS WINAPI NtQuerySecurityObject(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,ULONG,PULONG);
|
NTSTATUS WINAPI NtQuerySecurityObject(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,ULONG,PULONG);
|
||||||
NTSTATUS WINAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG);
|
NTSTATUS WINAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG);
|
||||||
NTSTATUS WINAPI NtQuerySystemTime(PLARGE_INTEGER);
|
NTSTATUS WINAPI NtQuerySystemTime(PLARGE_INTEGER);
|
||||||
|
NTSTATUS WINAPI NtQueryTimer(HANDLE,TIMER_INFORMATION_CLASS,PVOID,ULONG,PULONG);
|
||||||
NTSTATUS WINAPI NtQueryValueKey(HKEY,const UNICODE_STRING *,KEY_VALUE_INFORMATION_CLASS,void *,DWORD,DWORD *);
|
NTSTATUS WINAPI NtQueryValueKey(HKEY,const UNICODE_STRING *,KEY_VALUE_INFORMATION_CLASS,void *,DWORD,DWORD *);
|
||||||
NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE,LPCVOID,MEMORY_INFORMATION_CLASS,PVOID,ULONG,ULONG*);
|
NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE,LPCVOID,MEMORY_INFORMATION_CLASS,PVOID,ULONG,ULONG*);
|
||||||
NTSTATUS WINAPI NtQueryVolumeInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS);
|
NTSTATUS WINAPI NtQueryVolumeInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS);
|
||||||
|
@ -1378,6 +1378,14 @@ enum char_info_mode
|
|||||||
int signaled; /* was the timer signaled before this calltime ? */
|
int signaled; /* was the timer signaled before this calltime ? */
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
/* Get information on a waitable timer */
|
||||||
|
@REQ(get_timer_info)
|
||||||
|
obj_handle_t handle; /* handle to the timer */
|
||||||
|
@REPLY
|
||||||
|
abs_time_t when; /* absolute time when the timer next expires */
|
||||||
|
int signaled; /* is the timer signaled? */
|
||||||
|
@END
|
||||||
|
|
||||||
|
|
||||||
/* Retrieve the current context of a thread */
|
/* Retrieve the current context of a thread */
|
||||||
@REQ(get_thread_context)
|
@REQ(get_thread_context)
|
||||||
|
@ -209,6 +209,7 @@ DECL_HANDLER(create_timer);
|
|||||||
DECL_HANDLER(open_timer);
|
DECL_HANDLER(open_timer);
|
||||||
DECL_HANDLER(set_timer);
|
DECL_HANDLER(set_timer);
|
||||||
DECL_HANDLER(cancel_timer);
|
DECL_HANDLER(cancel_timer);
|
||||||
|
DECL_HANDLER(get_timer_info);
|
||||||
DECL_HANDLER(get_thread_context);
|
DECL_HANDLER(get_thread_context);
|
||||||
DECL_HANDLER(set_thread_context);
|
DECL_HANDLER(set_thread_context);
|
||||||
DECL_HANDLER(get_selector_entry);
|
DECL_HANDLER(get_selector_entry);
|
||||||
@ -393,6 +394,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||||||
(req_handler)req_open_timer,
|
(req_handler)req_open_timer,
|
||||||
(req_handler)req_set_timer,
|
(req_handler)req_set_timer,
|
||||||
(req_handler)req_cancel_timer,
|
(req_handler)req_cancel_timer,
|
||||||
|
(req_handler)req_get_timer_info,
|
||||||
(req_handler)req_get_thread_context,
|
(req_handler)req_get_thread_context,
|
||||||
(req_handler)req_set_thread_context,
|
(req_handler)req_set_thread_context,
|
||||||
(req_handler)req_get_selector_entry,
|
(req_handler)req_get_selector_entry,
|
||||||
|
@ -241,3 +241,18 @@ DECL_HANDLER(cancel_timer)
|
|||||||
release_object( timer );
|
release_object( timer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get information on a waitable timer */
|
||||||
|
DECL_HANDLER(get_timer_info)
|
||||||
|
{
|
||||||
|
struct timer *timer;
|
||||||
|
|
||||||
|
if ((timer = (struct timer *)get_handle_obj( current->process, req->handle,
|
||||||
|
TIMER_QUERY_STATE, &timer_ops )))
|
||||||
|
{
|
||||||
|
reply->when.sec = timer->when.tv_sec;
|
||||||
|
reply->when.usec = timer->when.tv_usec;
|
||||||
|
reply->signaled = timer->signaled;
|
||||||
|
release_object( timer );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1692,6 +1692,19 @@ static void dump_cancel_timer_reply( const struct cancel_timer_reply *req )
|
|||||||
fprintf( stderr, " signaled=%d", req->signaled );
|
fprintf( stderr, " signaled=%d", req->signaled );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dump_get_timer_info_request( const struct get_timer_info_request *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " handle=%p", req->handle );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_get_timer_info_reply( const struct get_timer_info_reply *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " when=" );
|
||||||
|
dump_abs_time( &req->when );
|
||||||
|
fprintf( stderr, "," );
|
||||||
|
fprintf( stderr, " signaled=%d", req->signaled );
|
||||||
|
}
|
||||||
|
|
||||||
static void dump_get_thread_context_request( const struct get_thread_context_request *req )
|
static void dump_get_thread_context_request( const struct get_thread_context_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " handle=%p,", req->handle );
|
fprintf( stderr, " handle=%p,", req->handle );
|
||||||
@ -2695,6 +2708,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||||||
(dump_func)dump_open_timer_request,
|
(dump_func)dump_open_timer_request,
|
||||||
(dump_func)dump_set_timer_request,
|
(dump_func)dump_set_timer_request,
|
||||||
(dump_func)dump_cancel_timer_request,
|
(dump_func)dump_cancel_timer_request,
|
||||||
|
(dump_func)dump_get_timer_info_request,
|
||||||
(dump_func)dump_get_thread_context_request,
|
(dump_func)dump_get_thread_context_request,
|
||||||
(dump_func)dump_set_thread_context_request,
|
(dump_func)dump_set_thread_context_request,
|
||||||
(dump_func)dump_get_selector_entry_request,
|
(dump_func)dump_get_selector_entry_request,
|
||||||
@ -2876,6 +2890,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||||||
(dump_func)dump_open_timer_reply,
|
(dump_func)dump_open_timer_reply,
|
||||||
(dump_func)dump_set_timer_reply,
|
(dump_func)dump_set_timer_reply,
|
||||||
(dump_func)dump_cancel_timer_reply,
|
(dump_func)dump_cancel_timer_reply,
|
||||||
|
(dump_func)dump_get_timer_info_reply,
|
||||||
(dump_func)dump_get_thread_context_reply,
|
(dump_func)dump_get_thread_context_reply,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)dump_get_selector_entry_reply,
|
(dump_func)dump_get_selector_entry_reply,
|
||||||
@ -3057,6 +3072,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||||||
"open_timer",
|
"open_timer",
|
||||||
"set_timer",
|
"set_timer",
|
||||||
"cancel_timer",
|
"cancel_timer",
|
||||||
|
"get_timer_info",
|
||||||
"get_thread_context",
|
"get_thread_context",
|
||||||
"set_thread_context",
|
"set_thread_context",
|
||||||
"get_selector_entry",
|
"get_selector_entry",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user