303 lines
12 KiB
C#
303 lines
12 KiB
C#
// ==++==
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// ==--==
|
|
//
|
|
// <OWNER>[....]</OWNER>
|
|
/*=============================================================================
|
|
**
|
|
** Class: EventWaitHandle
|
|
**
|
|
**
|
|
** Purpose: Base class for representing Events
|
|
**
|
|
**
|
|
=============================================================================*/
|
|
|
|
|
|
#if !FEATURE_MACL
|
|
namespace System.Security.AccessControl
|
|
{
|
|
public class EventWaitHandleSecurity
|
|
{
|
|
}
|
|
public enum EventWaitHandleRights
|
|
{
|
|
}
|
|
}
|
|
#endif
|
|
|
|
namespace System.Threading
|
|
{
|
|
using System;
|
|
using System.Threading;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Security.Permissions;
|
|
using System.IO;
|
|
using Microsoft.Win32;
|
|
using Microsoft.Win32.SafeHandles;
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.Versioning;
|
|
using System.Security.AccessControl;
|
|
using System.Diagnostics.Contracts;
|
|
|
|
[HostProtection(Synchronization=true, ExternalThreading=true)]
|
|
[ComVisibleAttribute(true)]
|
|
public class EventWaitHandle : WaitHandle
|
|
{
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.None)]
|
|
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
|
public EventWaitHandle(bool initialState, EventResetMode mode) : this(initialState,mode,null) { }
|
|
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
public EventWaitHandle(bool initialState, EventResetMode mode, string name)
|
|
{
|
|
if(null != name && System.IO.Path.MAX_PATH < name.Length)
|
|
{
|
|
throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong",name));
|
|
}
|
|
Contract.EndContractBlock();
|
|
|
|
SafeWaitHandle _handle = null;
|
|
switch(mode)
|
|
{
|
|
case EventResetMode.ManualReset:
|
|
_handle = Win32Native.CreateEvent(null, true, initialState, name);
|
|
break;
|
|
case EventResetMode.AutoReset:
|
|
_handle = Win32Native.CreateEvent(null, false, initialState, name);
|
|
break;
|
|
|
|
default:
|
|
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag",name));
|
|
};
|
|
|
|
if (_handle.IsInvalid)
|
|
{
|
|
int errorCode = Marshal.GetLastWin32Error();
|
|
|
|
_handle.SetHandleAsInvalid();
|
|
if(null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
|
|
throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle",name));
|
|
|
|
__Error.WinIOError(errorCode, name);
|
|
}
|
|
SetHandleInternal(_handle);
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew)
|
|
: this(initialState, mode, name, out createdNew, null)
|
|
{
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
public unsafe EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew, EventWaitHandleSecurity eventSecurity)
|
|
{
|
|
if(null != name && System.IO.Path.MAX_PATH < name.Length)
|
|
{
|
|
throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong",name));
|
|
}
|
|
Contract.EndContractBlock();
|
|
Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
|
|
#if FEATURE_MACL
|
|
// For ACL's, get the security descriptor from the EventWaitHandleSecurity.
|
|
if (eventSecurity != null) {
|
|
secAttrs = new Win32Native.SECURITY_ATTRIBUTES();
|
|
secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);
|
|
|
|
byte[] sd = eventSecurity.GetSecurityDescriptorBinaryForm();
|
|
byte* pSecDescriptor = stackalloc byte[sd.Length];
|
|
Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length);
|
|
secAttrs.pSecurityDescriptor = pSecDescriptor;
|
|
}
|
|
#endif
|
|
|
|
SafeWaitHandle _handle = null;
|
|
Boolean isManualReset;
|
|
switch(mode)
|
|
{
|
|
case EventResetMode.ManualReset:
|
|
isManualReset = true;
|
|
break;
|
|
case EventResetMode.AutoReset:
|
|
isManualReset = false;
|
|
break;
|
|
|
|
default:
|
|
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag",name));
|
|
};
|
|
|
|
_handle = Win32Native.CreateEvent(secAttrs, isManualReset, initialState, name);
|
|
int errorCode = Marshal.GetLastWin32Error();
|
|
|
|
if (_handle.IsInvalid)
|
|
{
|
|
|
|
_handle.SetHandleAsInvalid();
|
|
if(null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
|
|
throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle",name));
|
|
|
|
__Error.WinIOError(errorCode, name);
|
|
}
|
|
createdNew = errorCode != Win32Native.ERROR_ALREADY_EXISTS;
|
|
SetHandleInternal(_handle);
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
private EventWaitHandle(SafeWaitHandle handle)
|
|
{
|
|
SetHandleInternal(handle);
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
public static EventWaitHandle OpenExisting(string name)
|
|
{
|
|
#if !FEATURE_MACL
|
|
return OpenExisting(name, (EventWaitHandleRights)0);
|
|
#else
|
|
return OpenExisting(name, EventWaitHandleRights.Modify | EventWaitHandleRights.Synchronize);
|
|
#endif // !FEATURE_PAL
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
public static EventWaitHandle OpenExisting(string name, EventWaitHandleRights rights)
|
|
{
|
|
EventWaitHandle result;
|
|
switch (OpenExistingWorker(name, rights, out result))
|
|
{
|
|
case OpenExistingResult.NameNotFound:
|
|
throw new WaitHandleCannotBeOpenedException();
|
|
|
|
case OpenExistingResult.NameInvalid:
|
|
throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", name));
|
|
|
|
case OpenExistingResult.PathNotFound:
|
|
__Error.WinIOError(Win32Native.ERROR_PATH_NOT_FOUND, "");
|
|
return result; //never executes
|
|
|
|
default:
|
|
return result;
|
|
}
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
public static bool TryOpenExisting(string name, out EventWaitHandle result)
|
|
{
|
|
#if !FEATURE_MACL
|
|
return OpenExistingWorker(name, (EventWaitHandleRights)0, out result) == OpenExistingResult.Success;
|
|
#else
|
|
return OpenExistingWorker(name, EventWaitHandleRights.Modify | EventWaitHandleRights.Synchronize, out result) == OpenExistingResult.Success;
|
|
#endif // !FEATURE_PAL
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
public static bool TryOpenExisting(string name, EventWaitHandleRights rights, out EventWaitHandle result)
|
|
{
|
|
return OpenExistingWorker(name, rights, out result) == OpenExistingResult.Success;
|
|
}
|
|
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
[ResourceExposure(ResourceScope.Machine)]
|
|
[ResourceConsumption(ResourceScope.Machine)]
|
|
private static OpenExistingResult OpenExistingWorker(string name, EventWaitHandleRights rights, out EventWaitHandle result)
|
|
{
|
|
if (name == null)
|
|
{
|
|
throw new ArgumentNullException("name", Environment.GetResourceString("ArgumentNull_WithParamName"));
|
|
}
|
|
|
|
if(name.Length == 0)
|
|
{
|
|
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
|
|
}
|
|
|
|
if(null != name && System.IO.Path.MAX_PATH < name.Length)
|
|
{
|
|
throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong",name));
|
|
}
|
|
|
|
Contract.EndContractBlock();
|
|
|
|
result = null;
|
|
|
|
#if FEATURE_MACL
|
|
SafeWaitHandle myHandle = Win32Native.OpenEvent((int) rights, false, name);
|
|
#else
|
|
SafeWaitHandle myHandle = Win32Native.OpenEvent(Win32Native.EVENT_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name);
|
|
#endif
|
|
|
|
if (myHandle.IsInvalid)
|
|
{
|
|
int errorCode = Marshal.GetLastWin32Error();
|
|
|
|
if(Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode)
|
|
return OpenExistingResult.NameNotFound;
|
|
if (Win32Native.ERROR_PATH_NOT_FOUND == errorCode)
|
|
return OpenExistingResult.PathNotFound;
|
|
if(null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
|
|
return OpenExistingResult.NameInvalid;
|
|
//this is for passed through Win32Native Errors
|
|
__Error.WinIOError(errorCode,"");
|
|
}
|
|
result = new EventWaitHandle(myHandle);
|
|
return OpenExistingResult.Success;
|
|
}
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
public bool Reset()
|
|
{
|
|
bool res = Win32Native.ResetEvent(safeWaitHandle);
|
|
if (!res)
|
|
__Error.WinIOError();
|
|
return res;
|
|
}
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
public bool Set()
|
|
{
|
|
bool res = Win32Native.SetEvent(safeWaitHandle);
|
|
|
|
if (!res)
|
|
__Error.WinIOError();
|
|
|
|
return res;
|
|
}
|
|
|
|
#if FEATURE_MACL
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
public EventWaitHandleSecurity GetAccessControl()
|
|
{
|
|
return new EventWaitHandleSecurity(safeWaitHandle, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
public void SetAccessControl(EventWaitHandleSecurity eventSecurity)
|
|
{
|
|
if (eventSecurity == null)
|
|
throw new ArgumentNullException("eventSecurity");
|
|
Contract.EndContractBlock();
|
|
|
|
eventSecurity.Persist(safeWaitHandle);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|