mirror of
https://github.com/reactos/reactos.git
synced 2025-01-11 16:51:06 +00:00
c424146e2c
svn path=/branches/cmake-bringup/; revision=48236
296 lines
7.6 KiB
C
296 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 */
|