Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / SMDiagnostics / System / ServiceModel / Diagnostics / EventLogger.cs / 3 / EventLogger.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Diagnostics { using System.Diagnostics; using System.Globalization; using System.Security; using System.Security.Principal; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Text; using System.Security.Permissions; using System.Runtime.CompilerServices; class EventLogger { // In PT log no more than 5 events [SecurityRequiresReview] internal const int MaxEventLogsInPT = 5; DiagnosticTrace diagnosticTrace; ////// Critical - Protect the string that defines the event source name /// TreatAsSafe - It demands UnmanagedCode=true so PT cannot call /// [SecurityCritical] string eventLogSourceName; bool isInPatialTrust = false; private EventLogger() { isInPatialTrust = IsInPartialTrust(); } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.EventLog instead")] internal EventLogger(string eventLogSourceName, object diagnosticTrace) { try { this.diagnosticTrace = (DiagnosticTrace)diagnosticTrace; //set diagnostics trace prior to calling SafeSetLogSourceName if (canLogEvent) { SafeSetLogSourceName(eventLogSourceName); } } catch (SecurityException) { // running in PT, do not try to log events anymore canLogEvent = false; // not throwing exception on purpose } } ////// Critical - Protect the string that defines the event source name /// TreatAsSafe - It demands UnmanagedCode=true so PT cannot call /// [SecurityCritical, SecurityTreatAsSafe] [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] void SafeSetLogSourceName(string eventLogSourceName) { this.eventLogSourceName = eventLogSourceName; } ////// Critical - Sets event source name /// [SecurityCritical] void SetLogSourceName(string eventLogSourceName, object diagnosticTrace) { this.eventLogSourceName = eventLogSourceName; this.diagnosticTrace = (DiagnosticTrace)diagnosticTrace; } ////// Critical - Unsafe method to create event logger (sets the event source name) /// [SecurityCritical] internal static EventLogger UnsafeCreateEventLogger(string eventLogSourceName, object diagnosticTrace) { EventLogger logger = new EventLogger(); logger.SetLogSourceName(eventLogSourceName, diagnosticTrace); return logger; } private bool IsInPartialTrust() { bool retval = false; try { using (Process process = Process.GetCurrentProcess()) { retval = string.IsNullOrEmpty(process.ProcessName); } } catch (SecurityException) { // we are just testing, ignore exception retval = true; } return retval; } //// Converts incompatible serverity enumeration TraceEvetType into EventLogEntryType // static EventLogEntryType EventLogEntryTypeFromEventType(TraceEventType type) { EventLogEntryType retval = EventLogEntryType.Information; switch (type) { case TraceEventType.Critical: case TraceEventType.Error: retval = EventLogEntryType.Error; break; case TraceEventType.Warning: retval = EventLogEntryType.Warning; break; } return retval; } static bool canLogEvent = true; internal void LogEvent(TraceEventType type, EventLogCategory category, EventLogEventId eventId, bool shouldTrace, params string[] values) { if (canLogEvent) { try { SafeLogEvent(type, category, eventId, shouldTrace, values); } catch (SecurityException ex) { // running in PT, do not try to log events anymore canLogEvent = false; // not throwing exception on purpose if (shouldTrace && this.diagnosticTrace != null) { this.diagnosticTrace.TraceEvent(TraceEventType.Warning, TraceCode.TraceHandledException, TraceSR.GetString(TraceSR.TraceHandledException), null, ex, null); } } } } ////// Critical - Logs event to the event log by calling unsafe method /// Safe - Demands the same permission that is asserted by the unsafe method /// [SecurityCritical, SecurityTreatAsSafe] [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] internal void SafeLogEvent(TraceEventType type, EventLogCategory category, EventLogEventId eventId, bool shouldTrace, params string[] values) { UnsafeLogEvent(type, category, eventId, shouldTrace, values); } [SecurityCritical] static int logCountForPT; #pragma warning disable 56500, 56523 ////// Critical - Logs event to the event log and asserts Unmanaged code /// [SecurityCritical] internal void UnsafeLogEvent(TraceEventType type, EventLogCategory category, EventLogEventId eventId, bool shouldTrace, params string[] values) { if (logCountForPT < MaxEventLogsInPT) { try { // Vista introduces a new limitation: a much smaller max // event log entry size that we need to track. All strings cannot // exceed 31839 characters in length when totalled together. // Choose a max length of 25600 characters (25k) to allow for // buffer since this max length may be reduced without warning. const int MaxEventLogEntryLength = 25600; int eventLogEntryLength = 0; string[] logValues = new string[values.Length + 2]; for (int i = 0; i < values.Length; ++i) { string stringValue = values[i]; if (!string.IsNullOrEmpty(stringValue)) { stringValue = NormalizeEventLogParameter(stringValue); } else { stringValue = String.Empty; } logValues[i] = stringValue; eventLogEntryLength += stringValue.Length + 1; } string normalizedProcessName = NormalizeEventLogParameter(UnsafeGetProcessName()); logValues[logValues.Length - 2] = normalizedProcessName; eventLogEntryLength += (normalizedProcessName.Length + 1); string invariantProcessId = UnsafeGetProcessId().ToString(CultureInfo.InvariantCulture); logValues[logValues.Length - 1] = invariantProcessId; eventLogEntryLength += (invariantProcessId.Length + 1); // If current event log entry length is greater than max length // need to truncate to max length. This probably means that we // have a very long exception and stack trace in our parameter // strings. Truncate each string by MaxEventLogEntryLength // divided by number of strings in the entry. // Truncation algorithm is overly aggressive by design to // simplify the code change due to Product Cycle timing. if (eventLogEntryLength > MaxEventLogEntryLength) { // logValues.Length is always > 0 (minimum value = 2) // Subtract one to insure string ends in '\0' int truncationLength = (MaxEventLogEntryLength / logValues.Length) - 1; for (int i = 0; i < logValues.Length; i++) { if (logValues[i].Length > truncationLength) { logValues[i] = logValues[i].Substring(0, truncationLength); } } } SecurityIdentifier sid = WindowsIdentity.GetCurrent().User; byte[] sidBA = new byte[sid.BinaryLength]; sid.GetBinaryForm(sidBA, 0); IntPtr[] stringRoots = new IntPtr[logValues.Length]; GCHandle stringsRootHandle = new GCHandle(); GCHandle[] stringHandles = null; try { stringsRootHandle = GCHandle.Alloc(stringRoots, GCHandleType.Pinned); stringHandles = new GCHandle[logValues.Length]; for (int strIndex = 0; strIndex < logValues.Length; strIndex++) { stringHandles[strIndex] = GCHandle.Alloc(logValues[strIndex], GCHandleType.Pinned); stringRoots[strIndex] = stringHandles[strIndex].AddrOfPinnedObject(); } UnsafeWriteEventLog(type, category, eventId, logValues, sidBA, stringsRootHandle); } finally { if (stringsRootHandle.AddrOfPinnedObject() != IntPtr.Zero) { stringsRootHandle.Free(); } if (stringHandles != null) { foreach (GCHandle gcHandle in stringHandles) { if (gcHandle != null) { gcHandle.Free(); } } } } if (shouldTrace && this.diagnosticTrace != null) { const int RequiredValueCount = 4; DictionaryeventValues = new Dictionary (logValues.Length + RequiredValueCount); eventValues["CategoryID.Name"] = category.ToString(); eventValues["CategoryID.Value"] = ((uint)category).ToString(CultureInfo.InvariantCulture); eventValues["InstanceID.Name"] = eventId.ToString(); eventValues["InstanceID.Value"] = ((uint)eventId).ToString(CultureInfo.InvariantCulture); for (int i = 0; i < values.Length; ++i) { eventValues.Add("Value" + i.ToString(CultureInfo.InvariantCulture), values[i] == null ? string.Empty : DiagnosticTrace.XmlEncode(values[i])); } this.diagnosticTrace.TraceEvent(type, TraceCode.EventLog, TraceSR.GetString(TraceSR.TraceCodeEventLog), new DictionaryTraceRecord(eventValues), null, null); } } catch (Exception e) { if (ExceptionUtility.IsFatal(e)) { throw; } // If not fatal, just eat the exception } // In PT, we only limit 5 event logging per session if (isInPatialTrust) { logCountForPT++; } } } [SecurityCritical] [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)] private void UnsafeWriteEventLog(TraceEventType type, EventLogCategory category, EventLogEventId eventId, string[] logValues, byte[] sidBA, GCHandle stringsRootHandle) { using (SafeEventLogWriteHandle handle = SafeEventLogWriteHandle.RegisterEventSource(null, this.eventLogSourceName)) { if (handle != null) { HandleRef data = new HandleRef(handle, stringsRootHandle.AddrOfPinnedObject()); NativeMethods.ReportEvent( handle, (ushort)EventLogEntryTypeFromEventType(type), (ushort)category, (uint)eventId, sidBA, (ushort)logValues.Length, 0, data, null); } } } #pragma warning restore 56500, 56523 [SecurityCritical] [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)] [MethodImpl(MethodImplOptions.NoInlining)] private string UnsafeGetProcessName() { string retval = null; using (Process process = Process.GetCurrentProcess()) { retval = process.ProcessName; } return retval; } [SecurityCritical] [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)] [MethodImpl(MethodImplOptions.NoInlining)] private int UnsafeGetProcessId() { int retval = -1; using (Process process = Process.GetCurrentProcess()) { retval = process.Id; } return retval; } internal void LogEvent(TraceEventType type, EventLogCategory category, EventLogEventId eventId, params string[] values) { this.LogEvent(type, category, eventId, true, values); } internal static string NormalizeEventLogParameter(string param) { if (param.IndexOf('%') < 0) { return param; } StringBuilder str = null; int len = param.Length; for (int i = 0; i < len; ++i) { char c = param[i]; // Not '%' if (c != '%') { if (str != null) str.Append(c); continue; } // Last char if ((i + 1) >= len) { if (str != null) str.Append(c); continue; } // Next char is not number if (param[i + 1] < '0' || param[i + 1] > '9') { if (str != null) str.Append(c); continue; } // initialize str builder if (str == null) { str = new StringBuilder(len + 2); for (int j = 0; j < i; ++j) { str.Append(param[j]); } } str.Append(c); str.Append(' '); } return str != null ? str.ToString() : param; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ThrowHelper.cs
- ThumbAutomationPeer.cs
- SqlTriggerAttribute.cs
- ExtendedPropertyDescriptor.cs
- ListControlStringCollectionEditor.cs
- ItemMap.cs
- Activator.cs
- SerialErrors.cs
- HtmlTableRowCollection.cs
- EtwTrackingParticipant.cs
- ImageDrawing.cs
- dataSvcMapFileLoader.cs
- XmlWrappingReader.cs
- MatrixTransform.cs
- Pkcs7Signer.cs
- SafeNativeMethods.cs
- MessageQueueException.cs
- MembershipPasswordException.cs
- SafeLocalMemHandle.cs
- UsernameTokenFactoryCredential.cs
- CurrentChangingEventManager.cs
- View.cs
- ParameterToken.cs
- UnaryNode.cs
- XmlSchemaAnyAttribute.cs
- ShortcutKeysEditor.cs
- CompareValidator.cs
- ObjectDataSource.cs
- RegexMatch.cs
- Int16Converter.cs
- FontWeight.cs
- TokenDescriptor.cs
- Binding.cs
- PerformanceCounterPermission.cs
- ContextMenu.cs
- PropertyIDSet.cs
- PermissionListSet.cs
- EdmType.cs
- SecurityAppliedMessage.cs
- XmlSchemaGroupRef.cs
- PagesChangedEventArgs.cs
- SqlServer2KCompatibilityCheck.cs
- ActiveXHost.cs
- BitmapEffectInput.cs
- DoubleMinMaxAggregationOperator.cs
- RowSpanVector.cs
- ScriptingJsonSerializationSection.cs
- OdbcConnectionString.cs
- OutputCacheProfile.cs
- _Win32.cs
- FormatException.cs
- InfocardExtendedInformationEntry.cs
- ReferenceService.cs
- X509SecurityTokenAuthenticator.cs
- FormatSettings.cs
- SoapEnumAttribute.cs
- ReachIDocumentPaginatorSerializerAsync.cs
- GridViewUpdateEventArgs.cs
- MetadataItemCollectionFactory.cs
- Permission.cs
- Expressions.cs
- AuthorizationRule.cs
- DetailsViewRow.cs
- TextParaLineResult.cs
- TableLayoutColumnStyleCollection.cs
- FullTextState.cs
- HelpKeywordAttribute.cs
- ValidatingPropertiesEventArgs.cs
- SchemaContext.cs
- ObjectListTitleAttribute.cs
- AssemblyNameProxy.cs
- Typeface.cs
- HorizontalAlignConverter.cs
- SystemWebCachingSectionGroup.cs
- MobileTemplatedControlDesigner.cs
- LinkedList.cs
- BindingExpressionUncommonField.cs
- MaxValueConverter.cs
- PermissionSetTriple.cs
- IntPtr.cs
- IndicCharClassifier.cs
- PageFunction.cs
- FixedHighlight.cs
- IpcManager.cs
- WindowsFormsHost.cs
- PropertyChangedEventManager.cs
- MsmqProcessProtocolHandler.cs
- ControlCollection.cs
- EventMap.cs
- ThaiBuddhistCalendar.cs
- WindowsEditBoxRange.cs
- CodeAttributeArgument.cs
- TranslateTransform.cs
- ServiceCredentialsSecurityTokenManager.cs
- ExpressionNode.cs
- UserInitiatedRoutedEventPermission.cs
- RootBrowserWindowAutomationPeer.cs
- KnownIds.cs
- InvokeProviderWrapper.cs
- QilGenerator.cs