- implemented a few new handles related functions in ntdll (mainly, NtQueryObject and NtSetInformationObject for the ObjectDataInformation class)
- implemented timer related functions in ntdll (NtCreateTimer, NtCancelTimer, NtOpenTimer, NtSetTimer, Nt(Get|Set)TimerResolution)
- extended a bit the wineserver protocol in order to fully implement those timer related functions
- rewrote some kernel32 functions to use those new ntdll features
NB: with this patch applied, scheduler/handle.c and scheduler/timer.c can be moved dlls/kernel
A+
-- Eric Pouech
Name: ntkrnl_24 ChangeLog: - implemented a few handle and timer management functions in ntdll - rewrote the kernel equivalents to call their ntdll counterparts License: X11 GenDate: 2003/05/18 18:30:32 UTC ModifiedFiles: dlls/ntdll/Makefile.in dlls/ntdll/nt.c dlls/ntdll/ntdll.spec dlls/ntdll/om.c include/winternl.h scheduler/handle.c scheduler/timer.c server/protocol.def server/timer.c AddedFiles: dlls/ntdll/timer.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/ntdll/Makefile.in,v retrieving revision 1.63 diff -u -u -r1.63 Makefile.in --- dlls/ntdll/Makefile.in 16 May 2003 00:05:08 -0000 1.63 +++ dlls/ntdll/Makefile.in 17 May 2003 09:28:52 -0000 @@ -91,6 +91,7 @@ sync.c \ thread.c \ time.c \ + timer.c \ virtual.c \ wcstring.c Index: dlls/ntdll/nt.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/ntdll/nt.c,v retrieving revision 1.50 diff -u -u -r1.50 nt.c --- dlls/ntdll/nt.c 12 Apr 2003 00:01:32 -0000 1.50 +++ dlls/ntdll/nt.c 14 May 2003 07:22:02 -0000 @@ -69,52 +69,6 @@ } LPCMESSAGE, *PLPCMESSAGE; /* - * Timer object - */ - -/************************************************************************** - * NtCreateTimer [NTDLL.@] - * ZwCreateTimer [NTDLL.@] - */ -NTSTATUS WINAPI NtCreateTimer( - OUT PHANDLE TimerHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN TIMER_TYPE TimerType) -{ - FIXME("(%p,0x%08lx,%p,0x%08x) stub\n", - TimerHandle,DesiredAccess,ObjectAttributes, TimerType); - dump_ObjectAttributes(ObjectAttributes); - return 0; -} -/************************************************************************** - * NtSetTimer [NTDLL.@] - * ZwSetTimer [NTDLL.@] - */ -NTSTATUS WINAPI NtSetTimer( - IN HANDLE TimerHandle, - IN PLARGE_INTEGER DueTime, - IN PTIMERAPCROUTINE TimerApcRoutine, - IN PVOID TimerContext, - IN BOOLEAN WakeTimer, - IN ULONG Period OPTIONAL, - OUT PBOOLEAN PreviousState OPTIONAL) -{ - FIXME("(%p,%p,%p,%p,%08x,0x%08lx,%p) stub\n", - TimerHandle,DueTime,TimerApcRoutine,TimerContext,WakeTimer,Period,PreviousState); - return 0; -} - -/****************************************************************************** - * NtQueryTimerResolution [NTDLL.@] - */ -NTSTATUS WINAPI NtQueryTimerResolution(DWORD x1,DWORD x2,DWORD x3) -{ - FIXME("(0x%08lx,0x%08lx,0x%08lx), stub!\n",x1,x2,x3); - return 1; -} - -/* * Process object */ Index: dlls/ntdll/ntdll.spec =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/ntdll/ntdll.spec,v retrieving revision 1.115 diff -u -u -r1.115 ntdll.spec --- dlls/ntdll/ntdll.spec 15 May 2003 04:20:43 -0000 1.115 +++ dlls/ntdll/ntdll.spec 15 May 2003 17:32:26 -0000 @@ -68,7 +68,7 @@ @ stdcall NtAllocateVirtualMemory(long ptr ptr ptr long long) @ stub NtCallbackReturn @ stub NtCancelIoFile -@ stub NtCancelTimer +@ stdcall NtCancelTimer(long ptr) @ stdcall NtClearEvent(long) @ stdcall NtClose(long) @ stub NtCloseObjectAuditAlarm @@ -144,7 +144,7 @@ @ stdcall NtOpenSymbolicLinkObject (long long long) @ stdcall NtOpenThread(ptr long ptr ptr) @ stdcall NtOpenThreadToken(long long long long) -@ stub NtOpenTimer +@ stdcall NtOpenTimer(ptr long ptr) @ stub NtPlugPlayControl @ stub NtPrivilegeCheck @ stub NtPrivilegeObjectAuditAlarm @@ -215,7 +215,7 @@ @ stub NtSetHighWaitLowThread @ stdcall NtSetInformationFile(long long long long long) @ stdcall NtSetInformationKey(long long ptr long) -@ stub NtSetInformationObject +@ stdcall NtSetInformationObject(long long ptr long) @ stdcall NtSetInformationProcess(long long long long) @ stdcall NtSetInformationThread(long long long long) @ stub NtSetInformationToken @@ -231,7 +231,7 @@ @ stub NtSetSystemPowerState @ stdcall NtSetSystemTime(ptr ptr) @ stdcall NtSetTimer(long ptr ptr ptr long long ptr) -@ stub NtSetTimerResolution +@ stdcall NtSetTimerResolution(long long ptr) @ stdcall NtSetValueKey(long long long long long long) @ stdcall NtSetVolumeInformationFile(long ptr ptr long long) @ stub NtShutdownSystem @@ -599,7 +599,7 @@ @ stdcall ZwAllocateVirtualMemory(long ptr ptr ptr long long) NtAllocateVirtualMemory @ stub ZwCallbackReturn @ stub ZwCancelIoFile -@ stub ZwCancelTimer +@ stdcall ZwCancelTimer(long ptr) NtCancelTimer @ stdcall ZwClearEvent(long) NtClearEvent @ stdcall ZwClose(long) NtClose @ stub ZwCloseObjectAuditAlarm @@ -674,7 +674,7 @@ @ stdcall ZwOpenSymbolicLinkObject (long long long) NtOpenSymbolicLinkObject @ stdcall ZwOpenThread(ptr long ptr ptr) NtOpenThread @ stdcall ZwOpenThreadToken(long long long long) NtOpenThreadToken -@ stub ZwOpenTimer +@ stdcall ZwOpenTimer(ptr long ptr) NtOpenTimer @ stub ZwPlugPlayControl @ stub ZwPrivilegeCheck @ stub ZwPrivilegeObjectAuditAlarm @@ -742,7 +742,7 @@ @ stub ZwSetHighWaitLowThread @ stdcall ZwSetInformationFile(long long long long long) NtSetInformationFile @ stdcall ZwSetInformationKey(long long ptr long) NtSetInformationKey -@ stub ZwSetInformationObject +@ stdcall ZwSetInformationObject(long long ptr long) NtSetInformationObject @ stdcall ZwSetInformationProcess(long long long long) NtSetInformationProcess @ stdcall ZwSetInformationThread(long long long long) NtSetInformationThread @ stub ZwSetInformationToken @@ -758,7 +758,7 @@ @ stub ZwSetSystemPowerState @ stdcall ZwSetSystemTime(ptr ptr) NtSetSystemTime @ stdcall ZwSetTimer(long ptr ptr ptr long long ptr) NtSetTimer -@ stub ZwSetTimerResolution +@ stdcall ZwSetTimerResolution(long long) NtSetTimerResolution @ stdcall ZwSetValueKey(long long long long long long) NtSetValueKey @ stdcall ZwSetVolumeInformationFile(long ptr ptr long long) NtSetVolumeInformationFile @ stub ZwShutdownSystem Index: dlls/ntdll/om.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/ntdll/om.c,v retrieving revision 1.26 diff -u -u -r1.26 om.c --- dlls/ntdll/om.c 31 Mar 2003 01:37:05 -0000 1.26 +++ dlls/ntdll/om.c 13 May 2003 20:49:43 -0000 @@ -47,16 +47,93 @@ * NtQueryObject [NTDLL.@] * ZwQueryObject [NTDLL.@] */ -NTSTATUS WINAPI NtQueryObject( - IN HANDLE ObjectHandle, - IN OBJECT_INFORMATION_CLASS ObjectInformationClass, - OUT PVOID ObjectInformation, - IN ULONG Length, - OUT PULONG ResultLength) +NTSTATUS WINAPI NtQueryObject(IN HANDLE handle, + IN OBJECT_INFORMATION_CLASS info_class, + OUT PVOID ptr, IN ULONG len, OUT PULONG used_len) { - FIXME("(%p,0x%08x,%p,0x%08lx,%p): stub\n", - ObjectHandle, ObjectInformationClass, ObjectInformation, Length, ResultLength); - return 0; + DWORD status; + + TRACE("(%p,0x%08x,%p,0x%08lx,%p): stub\n", + handle, info_class, ptr, len, used_len); + + if (used_len) *used_len = 0; + + switch (info_class) + { + case ObjectDataInformation: + { + OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr; + + if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE; + + SERVER_START_REQ( set_handle_info ) + { + req->handle = handle; + req->flags = 0; + req->mask = 0; + req->fd = -1; + status = wine_server_call( req ); + if (status == STATUS_SUCCESS) + { + p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE; + p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ? TRUE : FALSE; + if (used_len) *used_len = sizeof(*p); + } + } + SERVER_END_REQ; + } + break; + default: + FIXME("Unsupported information class %u\n", info_class); + status = STATUS_NOT_IMPLEMENTED; + break; + } + return status; +} + +/****************************************************************** + * NtSetInformationObject [NTDLL.@] + * ZwSetInformationObject [NTDLL.@] + * + */ +NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle, + IN OBJECT_INFORMATION_CLASS info_class, + IN PVOID ptr, IN ULONG len) +{ + DWORD status; + + TRACE("(%p,0x%08x,%p,0x%08lx): stub\n", + handle, info_class, ptr, len); + + switch (info_class) + { + case ObjectDataInformation: + { + OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr; + unsigned m = 0; + + if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE; + + if (p->InheritHandle) m |= HANDLE_FLAG_INHERIT; + if (p->ProtectFromClose) m |= HANDLE_FLAG_PROTECT_FROM_CLOSE; + + SERVER_START_REQ( set_handle_info ) + { + req->handle = handle; + req->flags = m; + req->mask = m; + req->fd = -1; + status = wine_server_call( req ); + } + SERVER_END_REQ; + } + break; + default: + FIXME("Unsupported information class %u\n", info_class); + status = STATUS_NOT_IMPLEMENTED; + break; + } + return status; } /****************************************************************************** Index: include/winternl.h =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/include/winternl.h,v retrieving revision 1.35 diff -u -u -r1.35 winternl.h --- include/winternl.h 15 May 2003 04:20:43 -0000 1.35 +++ include/winternl.h 15 May 2003 17:34:06 -0000 @@ -229,7 +229,11 @@ } KEY_VALUE_INFORMATION_CLASS; typedef enum _OBJECT_INFORMATION_CLASS { - DunnoTheConstants1 /* FIXME */ + ObjectBasicInformation, + ObjectNameInformation, + ObjectTypeInformation, + ObjectAllInformation, + ObjectDataInformation } OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS; typedef enum _PROCESSINFOCLASS { @@ -499,6 +503,11 @@ PVOID SecurityQualityOfService; /* type SECURITY_QUALITY_OF_SERVICE */ } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; +typedef struct _OBJECT_DATA_INFORMATION { + BOOLEAN InheritHandle; + BOOLEAN ProtectFromClose; +} OBJECT_DATA_INFORMATION, *POBJECT_DATA_INFORMATION; + typedef struct _PROCESS_BASIC_INFORMATION { #ifdef __WINESRC__ DWORD ExitStatus; @@ -855,6 +864,7 @@ NTSTATUS WINAPI NtAccessCheck(PSECURITY_DESCRIPTOR,HANDLE,ACCESS_MASK,PGENERIC_MAPPING,PPRIVILEGE_SET,PULONG,PULONG,PBOOLEAN); NTSTATUS WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD); NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,PVOID,ULONG*,ULONG,ULONG); +NTSTATUS WINAPI NtCancelTimer(HANDLE, BOOLEAN*); NTSTATUS WINAPI NtClearEvent(HANDLE); NTSTATUS WINAPI NtClose(HANDLE); NTSTATUS WINAPI NtCreateEvent(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES *,BOOLEAN,BOOLEAN); @@ -862,6 +872,7 @@ NTSTATUS WINAPI NtCreateKey(PHKEY,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG,const UNICODE_STRING*,ULONG,PULONG); NTSTATUS WINAPI NtCreateSection(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*,const LARGE_INTEGER*,ULONG,ULONG,HANDLE); NTSTATUS WINAPI NtCreateSemaphore(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG,ULONG); +NTSTATUS WINAPI NtCreateTimer(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*, TIMER_TYPE); NTSTATUS WINAPI NtDeleteKey(HKEY); NTSTATUS WINAPI NtDeleteValueKey(HKEY,const UNICODE_STRING *); NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,PVOID,ULONG,PVOID,ULONG); @@ -884,6 +895,7 @@ NTSTATUS WINAPI NtOpenSection(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*); NTSTATUS WINAPI NtOpenThread(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*,const CLIENT_ID*); NTSTATUS WINAPI NtOpenThreadToken(HANDLE,DWORD,BOOLEAN,HANDLE *); +NTSTATUS WINAPI NtOpenTimer(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*); NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG,ULONG*); NTSTATUS WINAPI NtPulseEvent(HANDLE,PULONG); NTSTATUS WINAPI NtQueueApcThread(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PTR); @@ -893,6 +905,7 @@ NTSTATUS WINAPI NtQueryInformationToken(HANDLE,DWORD,LPVOID,DWORD,LPDWORD); NTSTATUS WINAPI NtQueryKey(HKEY,KEY_INFORMATION_CLASS,void *,DWORD,DWORD *); NTSTATUS WINAPI NtQueryMultipleValueKey(HKEY,PVALENTW,ULONG,PVOID,ULONG,PULONG); +NTSTATUS WINAPI NtQueryObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG); NTSTATUS WINAPI NtQuerySecurityObject(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,ULONG,PULONG); NTSTATUS WINAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG); NTSTATUS WINAPI NtQuerySystemTime(PLARGE_INTEGER); @@ -910,8 +923,10 @@ NTSTATUS WINAPI NtSetDefaultLocale(BOOLEAN,LCID); NTSTATUS WINAPI NtSetEvent(HANDLE,PULONG); NTSTATUS WINAPI NtSetInformationKey(HKEY,const int,PVOID,ULONG); +NTSTATUS WINAPI NtSetInformationObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG); NTSTATUS WINAPI NtSetSecurityObject(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); NTSTATUS WINAPI NtSetSystemTime(const LARGE_INTEGER*,LARGE_INTEGER*); +NTSTATUS WINAPI NtSetTimer(HANDLE, const LARGE_INTEGER*, PTIMERAPCROUTINE, PVOID, BOOLEAN, ULONG, BOOLEAN*); NTSTATUS WINAPI NtSetValueKey(HKEY,const UNICODE_STRING *,ULONG,ULONG,const void *,ULONG); NTSTATUS WINAPI NtSuspendThread(HANDLE,PULONG); NTSTATUS WINAPI NtTerminateProcess(HANDLE,LONG); Index: scheduler/handle.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/scheduler/handle.c,v retrieving revision 1.35 diff -u -u -r1.35 handle.c --- scheduler/handle.c 21 Nov 2002 03:45:01 -0000 1.35 +++ scheduler/handle.c 13 May 2003 20:49:11 -0000 @@ -60,18 +60,23 @@ */ BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags ) { - BOOL ret; - SERVER_START_REQ( set_handle_info ) + OBJECT_DATA_INFORMATION odi; + ULONG len; + NTSTATUS status; + + status = NtQueryObject(handle, ObjectDataInformation, + &odi, sizeof(odi), &len); + + if (status != STATUS_SUCCESS) { - req->handle = handle; - req->flags = 0; - req->mask = 0; - req->fd = -1; - ret = !wine_server_call_err( req ); - if (ret && flags) *flags = reply->old_flags; + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; } - SERVER_END_REQ; - return ret; + *flags = 0; + if (odi.InheritHandle) *flags |= HANDLE_FLAG_INHERIT; + if (odi.ProtectFromClose) *flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE; + + return TRUE; } @@ -80,17 +85,29 @@ */ BOOL WINAPI SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags ) { - BOOL ret; - SERVER_START_REQ( set_handle_info ) + OBJECT_DATA_INFORMATION odi; + NTSTATUS status; + ULONG len; + + status = NtQueryObject(handle, ObjectDataInformation, + &odi, sizeof(odi), &len); + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + if (mask & HANDLE_FLAG_INHERIT) + odi.InheritHandle = flags & HANDLE_FLAG_INHERIT; + if (mask & HANDLE_FLAG_PROTECT_FROM_CLOSE) + odi.ProtectFromClose = flags & HANDLE_FLAG_PROTECT_FROM_CLOSE; + status = NtSetInformationObject(handle, ObjectDataInformation, + &odi, sizeof(odi)); + if (status != STATUS_SUCCESS) { - req->handle = handle; - req->flags = flags; - req->mask = mask; - req->fd = -1; - ret = !wine_server_call_err( req ); + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; } - SERVER_END_REQ; - return ret; + return TRUE; } Index: scheduler/timer.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/scheduler/timer.c,v retrieving revision 1.19 diff -u -u -r1.19 timer.c --- scheduler/timer.c 2 Apr 2003 22:49:00 -0000 1.19 +++ scheduler/timer.c 14 May 2003 16:04:39 -0000 @@ -59,24 +59,26 @@ */ HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWSTR name ) { - HANDLE ret; - DWORD len = name ? strlenW(name) : 0; - if (len >= MAX_PATH) + HANDLE handle; + NTSTATUS status; + UNICODE_STRING us; + DWORD attr = 0; + OBJECT_ATTRIBUTES oa; + + if (name) RtlInitUnicodeString(&us, name); + if (sa && (sa->nLength >= sizeof(*sa)) && sa->bInheritHandle) + attr |= OBJ_INHERIT; + InitializeObjectAttributes(&oa, name ? &us : NULL, attr, + NULL /* FIXME */, NULL /* FIXME */); + status = NtCreateTimer(&handle, TIMER_ALL_ACCESS, &oa, + manual ? NotificationTimer : SynchronizationTimer); + + if (status != STATUS_SUCCESS) { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; + SetLastError( RtlNtStatusToDosError(status) ); + return NULL; } - SERVER_START_REQ( create_timer ) - { - req->manual = manual; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - wine_server_add_data( req, name, len * sizeof(WCHAR) ); - SetLastError(0); - wine_server_call_err( req ); - ret = reply->handle; - } - SERVER_END_REQ; - return ret; + return handle; } @@ -103,23 +105,23 @@ */ HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name ) { - HANDLE ret; - DWORD len = name ? strlenW(name) : 0; - if (len >= MAX_PATH) - { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; - } - SERVER_START_REQ( open_timer ) + NTSTATUS status; + ULONG attr = 0; + UNICODE_STRING us; + HANDLE handle; + OBJECT_ATTRIBUTES oa; + + if (inherit) attr |= OBJ_INHERIT; + + if (name) RtlInitUnicodeString(&us, name); + InitializeObjectAttributes(&oa, name ? &us : NULL, attr, NULL /* FIXME */, NULL /* FIXME */); + status = NtOpenTimer(&handle, access, &oa); + if (status != STATUS_SUCCESS) { - req->access = access; - req->inherit = inherit; - wine_server_add_data( req, name, len * sizeof(WCHAR) ); - wine_server_call_err( req ); - ret = reply->handle; + SetLastError( RtlNtStatusToDosError(status) ); + return NULL; } - SERVER_END_REQ; - return ret; + return handle; } @@ -129,27 +131,15 @@ BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG period, PTIMERAPCROUTINE callback, LPVOID arg, BOOL resume ) { - BOOL ret; - - SERVER_START_REQ( set_timer ) + NTSTATUS status; + + status = NtSetTimer(handle, when, callback, arg, resume, period, NULL); + if (status != STATUS_SUCCESS) { - if (!when->s.LowPart && !when->s.HighPart) - { - /* special case to start timeout on now+period without too many calculations */ - req->expire.sec = 0; - req->expire.usec = 0; - } - else NTDLL_get_server_timeout( &req->expire, when ); - - req->handle = handle; - req->period = period; - req->callback = callback; - req->arg = arg; - if (resume) SetLastError( ERROR_NOT_SUPPORTED ); /* set error but can still succeed */ - ret = !wine_server_call_err( req ); + SetLastError( RtlNtStatusToDosError(status) ); + if (status != STATUS_TIMER_RESUME_IGNORED) return FALSE; } - SERVER_END_REQ; - return ret; + return TRUE; } @@ -158,21 +148,22 @@ */ BOOL WINAPI CancelWaitableTimer( HANDLE handle ) { - BOOL ret; - SERVER_START_REQ( cancel_timer ) + NTSTATUS status; + + status = NtCancelTimer(handle, NULL); + if (status != STATUS_SUCCESS) { - req->handle = handle; - ret = !wine_server_call_err( req ); + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; } - SERVER_END_REQ; - return ret; + return TRUE; } /*********************************************************************** * CreateTimerQueue (KERNEL32.@) */ -HANDLE WINAPI CreateTimerQueue() +HANDLE WINAPI CreateTimerQueue(void) { FIXME("stub\n"); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); Index: server/protocol.def =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/server/protocol.def,v retrieving revision 1.66 diff -u -u -r1.66 protocol.def --- server/protocol.def 15 May 2003 04:22:45 -0000 1.66 +++ server/protocol.def 15 May 2003 17:31:58 -0000 @@ -1442,11 +1442,15 @@ int period; /* timer period in ms */ void* callback; /* callback function */ void* arg; /* callback argument */ +@REPLY + int signaled; /* was the timer signaled before this call ? */ @END /* Cancel a waitable timer */ @REQ(cancel_timer) obj_handle_t handle; /* handle to the timer */ +@REPLY + int signaled; /* was the timer signaled before this calltime ? */ @END Index: server/timer.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/server/timer.c,v retrieving revision 1.22 diff -u -u -r1.22 timer.c --- server/timer.c 4 Apr 2003 22:26:34 -0000 1.22 +++ server/timer.c 14 May 2003 08:58:44 -0000 @@ -115,8 +115,10 @@ } /* cancel a running timer */ -static void cancel_timer( struct timer *timer ) +static int cancel_timer( struct timer *timer ) { + int signaled = timer->signaled; + if (timer->timeout) { remove_timeout_user( timer->timeout ); @@ -128,13 +130,14 @@ release_object( timer->thread ); timer->thread = NULL; } + return signaled; } /* set the timer expiration and period */ -static void set_timer( struct timer *timer, const abs_time_t *expire, int period, - void *callback, void *arg ) +static int set_timer( struct timer *timer, const abs_time_t *expire, int period, + void *callback, void *arg ) { - cancel_timer( timer ); + int signaled = cancel_timer( timer ); if (timer->manual) { period = 0; /* period doesn't make any sense for a manual timer */ @@ -156,6 +159,7 @@ timer->arg = arg; if (callback) timer->thread = (struct thread *)grab_object( current ); timer->timeout = add_timeout_user( &timer->when, timer_callback, timer ); + return signaled; } static void timer_dump( struct object *obj, int verbose ) @@ -220,7 +224,7 @@ if ((timer = (struct timer *)get_handle_obj( current->process, req->handle, TIMER_MODIFY_STATE, &timer_ops ))) { - set_timer( timer, &req->expire, req->period, req->callback, req->arg ); + reply->signaled = set_timer( timer, &req->expire, req->period, req->callback, req->arg ); release_object( timer ); } } @@ -233,7 +237,7 @@ if ((timer = (struct timer *)get_handle_obj( current->process, req->handle, TIMER_MODIFY_STATE, &timer_ops ))) { - cancel_timer( timer ); + reply->signaled = cancel_timer( timer ); release_object( timer ); } } --- /dev/null 1970-01-01 01:00:00.000000000 +0100 +++ dlls/ntdll/timer.c 2003-05-14 11:30:05.000000000 +0200 @@ -0,0 +1,176 @@ +/* + * NT DLL timer related function + * + * Copyright 1996-1998 Marcus Meissner + * 1999 Alexandre Julliard + * 2003 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#include "wine/debug.h" + +#include "winternl.h" +#include "ntdll_misc.h" +#include "wine/server.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ntdll); + +/************************************************************************** + * NtCreateTimer [NTDLL.@] + * ZwCreateTimer [NTDLL.@] + */ +NTSTATUS WINAPI NtCreateTimer(OUT HANDLE *handle, + IN ACCESS_MASK access, + IN const OBJECT_ATTRIBUTES *oa OPTIONAL, + IN TIMER_TYPE timer_type) +{ + NTSTATUS status; + + if (timer_type != NotificationTimer && timer_type != SynchronizationTimer) + return STATUS_INVALID_PARAMETER; + + SERVER_START_REQ( create_timer ) + { + req->manual = (timer_type == NotificationTimer) ? TRUE : FALSE; + req->inherit = oa && (oa->Attributes & OBJ_INHERIT); + if (oa && oa->ObjectName->Length) + wine_server_add_data( req, oa->ObjectName->Buffer, oa->ObjectName->Length ); + status = wine_server_call( req ); + *handle = reply->handle; + } + SERVER_END_REQ; + return status; + +} + +/************************************************************************** + * NtOpenTimer [NTDLL.@] + * ZwOpenTimer [NTDLL.@] + */ +NTSTATUS WINAPI NtOpenTimer(OUT PHANDLE handle, + IN ACCESS_MASK access, + IN const OBJECT_ATTRIBUTES* oa ) +{ + NTSTATUS status; + + if (oa && oa->Length >= MAX_PATH * sizeof(WCHAR)) + return STATUS_NAME_TOO_LONG; + + SERVER_START_REQ( open_timer ) + { + req->access = access; + req->inherit = oa && (oa->Attributes & OBJ_INHERIT); + if (oa && oa->ObjectName->Length) + wine_server_add_data( req, oa->ObjectName->Buffer, oa->ObjectName->Length ); + status = wine_server_call( req ); + *handle = reply->handle; + } + SERVER_END_REQ; + return status; +} + +/************************************************************************** + * NtSetTimer [NTDLL.@] + * ZwSetTimer [NTDLL.@] + */ +NTSTATUS WINAPI NtSetTimer(IN HANDLE handle, + IN const LARGE_INTEGER* when, + IN PTIMERAPCROUTINE callback, + IN PVOID callback_arg, + IN BOOLEAN resume, + IN ULONG period OPTIONAL, + OUT PBOOLEAN state OPTIONAL) +{ + NTSTATUS status = STATUS_SUCCESS; + + TRACE("(%p,%p,%p,%p,%08x,0x%08lx,%p) stub\n", + handle, when, callback, callback_arg, resume, period, state); + + SERVER_START_REQ( set_timer ) + { + if (!when->s.LowPart && !when->s.HighPart) + { + /* special case to start timeout on now+period without too many calculations */ + req->expire.sec = 0; + req->expire.usec = 0; + } + else NTDLL_get_server_timeout( &req->expire, when ); + + req->handle = handle; + req->period = period; + req->callback = callback; + req->arg = 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; +} + +/************************************************************************** + * NtCancelTimer [NTDLL.@] + * ZwCancelTimer [NTDLL.@] + */ +NTSTATUS WINAPI NtCancelTimer(IN HANDLE handle, OUT BOOLEAN* state) +{ + NTSTATUS status; + + SERVER_START_REQ( cancel_timer ) + { + req->handle = handle; + status = wine_server_call( req ); + if (state) *state = reply->signaled; + } + SERVER_END_REQ; + return status; +} + +/****************************************************************************** + * NtQueryTimerResolution [NTDLL.@] + */ +NTSTATUS WINAPI NtQueryTimerResolution(OUT ULONG* min_resolution, + OUT ULONG* max_resolution, + OUT ULONG* current_resolution) +{ + FIXME("(%p,%p,%p), stub!\n", + min_resolution, max_resolution, current_resolution); + + return STATUS_NOT_IMPLEMENTED; +} + +/****************************************************************************** + * NtSetTimerResolution [NTDLL.@] + */ +NTSTATUS WINAPI NtSetTimerResolution(IN ULONG resolution, + IN BOOLEAN set_resolution, + OUT ULONG* current_resolution ) +{ + FIXME("(%lu,%u,%p), stub!\n", + resolution, set_resolution, current_resolution); + + return STATUS_NOT_IMPLEMENTED; +} +