-
-
Save Iristyle/fc3abc4a2daccdded5186869892c1ce0 to your computer and use it in GitHub Desktop.
.NET CreateEventSource code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ResourceExposure(ResourceScope.None)] | |
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] | |
public static void CreateEventSource(EventSourceCreationData sourceData) { | |
if (sourceData == null) | |
throw new ArgumentNullException("sourceData"); | |
string logName = sourceData.LogName; | |
string source = sourceData.Source; | |
string machineName = sourceData.MachineName; | |
// verify parameters | |
Debug.WriteLineIf(CompModSwitches.EventLog.TraceVerbose, "CreateEventSource: Checking arguments"); | |
if (!SyntaxCheck.CheckMachineName(machineName)) { | |
throw new ArgumentException(SR.GetString(SR.InvalidParameter, "machineName", machineName)); | |
} | |
if (logName == null || logName.Length==0) | |
logName = "Application"; | |
if (!ValidLogName(logName, false)) | |
throw new ArgumentException(SR.GetString(SR.BadLogName)); | |
if (source == null || source.Length==0) | |
throw new ArgumentException(SR.GetString(SR.MissingParameter, "source")); | |
if (source.Length + EventLogKey.Length > 254) | |
throw new ArgumentException(SR.GetString(SR.ParameterTooLong, "source", 254 - EventLogKey.Length)); | |
EventLogPermission permission = new EventLogPermission(EventLogPermissionAccess.Administer, machineName); | |
permission.Demand(); | |
Mutex mutex = null; | |
RuntimeHelpers.PrepareConstrainedRegions(); | |
try { | |
SharedUtils.EnterMutex(eventLogMutexName, ref mutex); | |
Debug.WriteLineIf(CompModSwitches.EventLog.TraceVerbose, "CreateEventSource: Calling SourceExists"); | |
if (SourceExists(source, machineName, true)) { | |
Debug.WriteLineIf(CompModSwitches.EventLog.TraceVerbose, "CreateEventSource: SourceExists returned true"); | |
// don't let them register a source if it already exists | |
// this makes more sense than just doing it anyway, because the source might | |
// be registered under a different log name, and we don't want to create | |
// duplicates. | |
if (".".Equals(machineName)) | |
throw new ArgumentException(SR.GetString(SR.LocalSourceAlreadyExists, source)); | |
else | |
throw new ArgumentException(SR.GetString(SR.SourceAlreadyExists, source, machineName)); | |
} | |
Debug.WriteLineIf(CompModSwitches.EventLog.TraceVerbose, "CreateEventSource: Getting DllPath"); | |
//SECREVIEW: Note that EventLog permission is demanded above. | |
PermissionSet permissionSet = _UnsafeGetAssertPermSet(); | |
permissionSet.Assert(); | |
RegistryKey baseKey = null; | |
RegistryKey eventKey = null; | |
RegistryKey logKey = null; | |
RegistryKey sourceLogKey = null; | |
RegistryKey sourceKey = null; | |
try { | |
Debug.WriteLineIf(CompModSwitches.EventLog.TraceVerbose, "CreateEventSource: Getting local machine regkey"); | |
if (machineName == ".") | |
baseKey = Registry.LocalMachine; | |
else | |
baseKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, machineName); | |
eventKey = baseKey.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\EventLog", true); | |
if (eventKey == null) { | |
if (!".".Equals(machineName)) | |
throw new InvalidOperationException(SR.GetString(SR.RegKeyMissing, "SYSTEM\\CurrentControlSet\\Services\\EventLog", logName, source, machineName)); | |
else | |
throw new InvalidOperationException(SR.GetString(SR.LocalRegKeyMissing, "SYSTEM\\CurrentControlSet\\Services\\EventLog", logName, source)); | |
} | |
// The event log system only treats the first 8 characters of the log name as | |
// significant. If they're creating a new log, but that new log has the same | |
// first 8 characters as another log, the system will think they're the same. | |
// Throw an exception to let them know. | |
logKey = eventKey.OpenSubKey(logName, true); | |
if (logKey == null && logName.Length >= 8) { | |
// check for Windows embedded logs file names | |
string logNameFirst8 = logName.Substring(0,8); | |
if ( string.Compare(logNameFirst8,"AppEvent",StringComparison.OrdinalIgnoreCase) ==0 || | |
string.Compare(logNameFirst8,"SecEvent",StringComparison.OrdinalIgnoreCase) ==0 || | |
string.Compare(logNameFirst8,"SysEvent",StringComparison.OrdinalIgnoreCase) ==0 ) | |
throw new ArgumentException(SR.GetString(SR.InvalidCustomerLogName, logName)); | |
string sameLogName = FindSame8FirstCharsLog(eventKey, logName); | |
if ( sameLogName != null ) | |
throw new ArgumentException(SR.GetString(SR.DuplicateLogName, logName, sameLogName)); | |
} | |
bool createLogKey = (logKey == null); | |
if (createLogKey) { | |
if (SourceExists(logName, machineName, true)) { | |
// don't let them register a log name that already | |
// exists as source name, a source with the same | |
// name as the log will have to be created by default | |
if (".".Equals(machineName)) | |
throw new ArgumentException(SR.GetString(SR.LocalLogAlreadyExistsAsSource, logName)); | |
else | |
throw new ArgumentException(SR.GetString(SR.LogAlreadyExistsAsSource, logName, machineName)); | |
} | |
logKey = eventKey.CreateSubKey(logName); | |
// NOTE: We shouldn't set "Sources" explicitly, the OS will automatically set it. | |
// The EventLog service doesn't use it for anything it is just an helping hand for event viewer filters. | |
// Writing this value explicitly might confuse the service as it might perceive it as a change and | |
// start initializing again | |
if (!SkipRegPatch) | |
logKey.SetValue("Sources", new string[] {logName, source}, RegistryValueKind.MultiString); | |
SetSpecialLogRegValues(logKey, logName); | |
// A source with the same name as the log has to be created | |
// by default. It is the behavior expected by EventLog API. | |
sourceLogKey = logKey.CreateSubKey(logName); | |
SetSpecialSourceRegValues(sourceLogKey, sourceData); | |
} | |
if (logName != source) { | |
if (!createLogKey) { | |
SetSpecialLogRegValues(logKey, logName); | |
if (!SkipRegPatch) { | |
string[] sources = logKey.GetValue("Sources") as string[]; | |
if (sources == null) | |
logKey.SetValue("Sources", new string[] {logName, source}, RegistryValueKind.MultiString); | |
else { | |
// We have a ---- with OS EventLog here. | |
// OS might update Sources as well. We should avoid writing the | |
// source name if OS beats us. | |
if( Array.IndexOf(sources, source) == -1) { | |
string[] newsources = new string[sources.Length + 1]; | |
Array.Copy(sources, newsources, sources.Length); | |
newsources[sources.Length] = source; | |
logKey.SetValue("Sources", newsources, RegistryValueKind.MultiString); | |
} | |
} | |
} | |
} | |
sourceKey = logKey.CreateSubKey(source); | |
SetSpecialSourceRegValues(sourceKey, sourceData); | |
} | |
} | |
finally { | |
if (baseKey != null) | |
baseKey.Close(); | |
if (eventKey != null) | |
eventKey.Close(); | |
if (logKey != null) { | |
logKey.Flush(); | |
logKey.Close(); | |
} | |
if (sourceLogKey != null) { | |
sourceLogKey.Flush(); | |
sourceLogKey.Close(); | |
} | |
if (sourceKey != null) { | |
sourceKey.Flush(); | |
sourceKey.Close(); | |
} | |
// Revert registry and environment permission asserts | |
CodeAccessPermission.RevertAssert(); | |
} | |
} | |
finally { | |
if (mutex != null) { | |
mutex.ReleaseMutex(); | |
mutex.Close(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment