reactos/dll/win32/kernel32/synch/timer.c
Amine Khaldi c424146e2c Create a branch for cmake bringup.
svn path=/branches/cmake-bringup/; revision=48236
2010-07-24 18:52:44 +00:00

297 lines
7.6 KiB
C

/*
* 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 <k32.h>
#define NDEBUG
#include <debug.h>
/* 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 */