public static extern SafeWaitHandle CreateWaitableTimer(
     SECURITY_ATTRIBUTES timerAttributes,
     bool manualReset,
     string timerName);
 public static extern SafeWaitHandle CreateWaitableTimerEx(
     SECURITY_ATTRIBUTES timerAttributes,
     string timerName,
     Int32 flags,
     UInt32 desiredAccess);
        private unsafe SafeWaitHandle CreateTimerHandle(bool manualReset,
            string name,
            out bool createdNew,
            WaitableTimerSecurity timerSecurity)
        {
            if (name != null && name.Length > 260)
            {
                throw new ArgumentException("name is too long.");
            }

            SECURITY_ATTRIBUTES secattr = null;
            if (timerSecurity != null)
            {
                // Create a SECURITY_ATTRIBUTES class and populate it
                // from the information stored in timerSecurity
                secattr = new SECURITY_ATTRIBUTES();
                secattr.nLength = Marshal.SizeOf(secattr);
                byte[] binaryForm = timerSecurity.GetSecurityDescriptorBinaryForm();
                byte* pbin = stackalloc byte[binaryForm.Length];
                fixed (byte* psrc = binaryForm)
                {
                    for (int i = 0; i < binaryForm.Length; ++i)
                    {
                        *(pbin + i) = *(psrc + i);
                    }
                }
                secattr.lpSecurityDescriptor = (IntPtr)pbin;
            }

            SafeWaitHandle handle = Win32WaitableTimer.CreateWaitableTimer(secattr, manualReset, name);
            int lastError = Marshal.GetLastWin32Error();
            if (handle.IsInvalid)
            {
                if (name == null)
                {
                    throw GetWin32Exception();
                }
                if (lastError == Win32WaitableTimer.ERROR_INVALID_HANDLE)
                {
                    throw new WaitHandleCannotBeOpenedException("Invalid handle");
                }
                throw new WaitHandleCannotBeOpenedException();
            }
            createdNew = (Marshal.GetLastWin32Error() == Win32WaitableTimer.ERROR_ALREADY_EXISTS);
            return handle;
        }