diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index be63740cf1b..c7b1f43cdfd 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -3824,15 +3824,6 @@ void WINAPI IoInvalidateDeviceRelations( DEVICE_OBJECT *device_object, DEVICE_RE } } -/*********************************************************************** - * KeSetTimerEx (NTOSKRNL.EXE.@) - */ -BOOL WINAPI KeSetTimerEx( KTIMER *timer, LARGE_INTEGER duetime, LONG period, KDPC *dpc ) -{ - FIXME("stub: %p %s %u %p\n", timer, wine_dbgstr_longlong(duetime.QuadPart), period, dpc); - return TRUE; -} - /*********************************************************************** * IoCreateFile (NTOSKRNL.EXE.@) */ diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c index 910572b0ee2..06db1dec630 100644 --- a/dlls/ntoskrnl.exe/sync.c +++ b/dlls/ntoskrnl.exe/sync.c @@ -94,6 +94,9 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[], semaphore->Header.SignalState, semaphore->Limit, NULL ); break; } + case TYPE_MANUAL_TIMER: + case TYPE_AUTO_TIMER: + break; } } @@ -111,6 +114,7 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[], switch (objs[i]->Type) { case TYPE_AUTO_EVENT: + case TYPE_AUTO_TIMER: objs[i]->SignalState = FALSE; break; case TYPE_MUTEX: @@ -317,3 +321,30 @@ void WINAPI KeInitializeTimer( KTIMER *timer ) { KeInitializeTimerEx(timer, NotificationTimer); } + +/*********************************************************************** + * KeSetTimerEx (NTOSKRNL.EXE.@) + */ +BOOLEAN WINAPI KeSetTimerEx( KTIMER *timer, LARGE_INTEGER duetime, LONG period, KDPC *dpc ) +{ + BOOL manual = timer->Header.Type == TYPE_MANUAL_TIMER; + BOOL ret; + + TRACE("timer %p, duetime %s, period %d, dpc %p.\n", + timer, wine_dbgstr_longlong(duetime.QuadPart), period, dpc); + + if (dpc) + { + FIXME("Unhandled DPC %p.\n", dpc); + return FALSE; + } + + EnterCriticalSection( &sync_cs ); + ret = timer->Header.Inserted; + timer->Header.Inserted = TRUE; + timer->Header.WaitListHead.Blink = CreateWaitableTimerW( NULL, manual, NULL ); + SetWaitableTimer( timer->Header.WaitListHead.Blink, &duetime, period, NULL, NULL, FALSE ); + LeaveCriticalSection( &sync_cs ); + + return ret; +} diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 2b773b2780e..8472b09d49f 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1435,6 +1435,7 @@ LONG WINAPI KeResetEvent(PRKEVENT); LONG WINAPI KeSetEvent(PRKEVENT,KPRIORITY,BOOLEAN); KPRIORITY WINAPI KeSetPriorityThread(PKTHREAD,KPRIORITY); void WINAPI KeSetSystemAffinityThread(KAFFINITY); +BOOLEAN WINAPI KeSetTimerEx(KTIMER*,LARGE_INTEGER,LONG,KDPC*); NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG,void*[],WAIT_TYPE,KWAIT_REASON,KPROCESSOR_MODE,BOOLEAN,LARGE_INTEGER*,KWAIT_BLOCK*); NTSTATUS WINAPI KeWaitForSingleObject(void*,KWAIT_REASON,KPROCESSOR_MODE,BOOLEAN,LARGE_INTEGER*);