/* * PROJECT: ReactOS Win32 Base API * LICENSE: GPL - See COPYING in the top level directory * FILE: dll/win32/kernel32/synch/timer.c * PURPOSE: Wrappers for the NT Timer Implementation * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES *****************************************************************/ #include #define NDEBUG #include /* FUNCTIONS ****************************************************************/ /* * @implemented */ HANDLE WINAPI CreateWaitableTimerExA(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL, IN LPCSTR lpTimerName OPTIONAL, IN DWORD dwFlags, IN DWORD dwDesiredAccess) { NTSTATUS Status; ANSI_STRING AnsiName; PUNICODE_STRING UnicodeCache; LPCWSTR UnicodeName = NULL; /* Check for a name */ if (lpTimerName) { /* Use TEB Cache */ UnicodeCache = &NtCurrentTeb()->StaticUnicodeString; /* Convert to unicode */ RtlInitAnsiString(&AnsiName, lpTimerName); Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE); if (!NT_SUCCESS(Status)) { /* Conversion failed */ SetLastErrorByStatus(Status); return NULL; } /* Otherwise, save the buffer */ UnicodeName = (LPCWSTR)UnicodeCache->Buffer; } /* Call the Unicode API */ return CreateWaitableTimerExW(lpTimerAttributes, UnicodeName, dwFlags, dwDesiredAccess); } /* * @implemented */ HANDLE WINAPI CreateWaitableTimerExW(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL, IN LPCWSTR lpTimerName OPTIONAL, IN DWORD dwFlags, IN DWORD dwDesiredAccess) { NTSTATUS Status; OBJECT_ATTRIBUTES LocalAttributes; POBJECT_ATTRIBUTES ObjectAttributes; HANDLE Handle; UNICODE_STRING ObjectName; TIMER_TYPE TimerType; /* Now check if we got a name */ if (lpTimerName) RtlInitUnicodeString(&ObjectName, lpTimerName); if (dwFlags & ~(CREATE_WAITABLE_TIMER_MANUAL_RESET)) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; } TimerType = (dwFlags & CREATE_WAITABLE_TIMER_MANUAL_RESET) ? NotificationTimer : SynchronizationTimer; /* Now convert the object attributes */ ObjectAttributes = BasepConvertObjectAttributes(&LocalAttributes, lpTimerAttributes, lpTimerName ? &ObjectName : NULL); /* Create the timer */ Status = NtCreateTimer(&Handle, (ACCESS_MASK)dwDesiredAccess, ObjectAttributes, TimerType); if (NT_SUCCESS(Status)) { /* Check if the object already existed */ if (Status == STATUS_OBJECT_NAME_EXISTS) { /* Set distinguished Win32 error code */ SetLastError(ERROR_ALREADY_EXISTS); } else { /* Otherwise, set success */ SetLastError(ERROR_SUCCESS); } /* Return the handle */ return Handle; } else { /* Convert the NT Status and fail */ SetLastErrorByStatus(Status); return NULL; } } /* * @implemented */ HANDLE WINAPI CreateWaitableTimerW(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL, IN BOOL bManualReset, IN LPCWSTR lpTimerName OPTIONAL) { DWORD dwFlags = 0; if (bManualReset) dwFlags |= CREATE_WAITABLE_TIMER_MANUAL_RESET; return CreateWaitableTimerExW(lpTimerAttributes, lpTimerName, dwFlags, TIMER_ALL_ACCESS); } /* * @implemented */ HANDLE WINAPI CreateWaitableTimerA(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL, IN BOOL bManualReset, IN LPCSTR lpTimerName OPTIONAL) { DWORD dwFlags = 0; if (bManualReset) dwFlags |= CREATE_WAITABLE_TIMER_MANUAL_RESET; return CreateWaitableTimerExA(lpTimerAttributes, lpTimerName, dwFlags, TIMER_ALL_ACCESS); } /* * @implemented */ HANDLE WINAPI OpenWaitableTimerW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpTimerName) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING ObjectName; NTSTATUS Status; HANDLE Handle; /* Make sure we got a name */ if (!lpTimerName) { /* Fail without one */ SetLastErrorByStatus(STATUS_INVALID_PARAMETER); return NULL; } /* Initialize the object name and attributes */ RtlInitUnicodeString(&ObjectName, lpTimerName); InitializeObjectAttributes(&ObjectAttributes, &ObjectName, bInheritHandle ? OBJ_INHERIT : 0, hBaseDir, NULL); /* Open the timer */ Status = NtOpenTimer(&Handle, dwDesiredAccess, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* Convert the status and fail */ SetLastErrorByStatus(Status); return NULL; } /* Return the handle */ return Handle; } /* * @implemented */ HANDLE WINAPI OpenWaitableTimerA(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCSTR lpTimerName) { NTSTATUS Status; ANSI_STRING AnsiName; PUNICODE_STRING UnicodeCache; /* Check for a name */ if (lpTimerName) { /* Use TEB Cache */ UnicodeCache = &NtCurrentTeb()->StaticUnicodeString; /* Convert to unicode */ RtlInitAnsiString(&AnsiName, lpTimerName); Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE); if (!NT_SUCCESS(Status)) { /* Conversion failed */ SetLastErrorByStatus(Status); return NULL; } } else { /* We need a name */ SetLastError(ERROR_INVALID_PARAMETER); return NULL; } /* Call the Unicode API */ return OpenWaitableTimerW(dwDesiredAccess, bInheritHandle, (LPCWSTR)UnicodeCache->Buffer); } /* * @implemented */ BOOL WINAPI SetWaitableTimer(IN HANDLE hTimer, IN const LARGE_INTEGER *pDueTime, IN LONG lPeriod, IN PTIMERAPCROUTINE pfnCompletionRoutine OPTIONAL, IN OPTIONAL LPVOID lpArgToCompletionRoutine, IN BOOL fResume) { NTSTATUS Status; /* Set the timer */ Status = NtSetTimer(hTimer, (PLARGE_INTEGER)pDueTime, (PTIMER_APC_ROUTINE)pfnCompletionRoutine, lpArgToCompletionRoutine, (BOOLEAN)fResume, lPeriod, NULL); if (NT_SUCCESS(Status)) return TRUE; /* If we got here, then we failed */ SetLastErrorByStatus(Status); return FALSE; } /* * @implemented */ BOOL WINAPI CancelWaitableTimer(IN HANDLE hTimer) { NTSTATUS Status; /* Cancel the timer */ Status = NtCancelTimer(hTimer, NULL); if (NT_SUCCESS(Status)) return TRUE; /* If we got here, then we failed */ SetLastErrorByStatus(Status); return FALSE; } /* EOF */