ntdll/kernel32: #24

Eric Pouech pouech-eric at wanadoo.fr
Sun May 18 13:37:10 CDT 2003


This patch does the following:
- 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
-------------- next part --------------
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 */
+ at 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 */
+ at 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;
+}
+


More information about the wine-patches mailing list