Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Shared / MS / Utility / TraceProvider.cs / 1 / TraceProvider.cs
//----------------------------------------------------------------------------
// File: TraceProvider
//
// A Managed wrapper for Event Tracing for Windows
// Based on TraceEvent.cs found in nt\base\wmi\trace.net
// Provides an internal Avalon API to replace Microsoft.Windows.EventTracing.dll
//
//---------------------------------------------------------------------------
using System;
using MS.Win32;
using MS.Internal;
using System.Runtime.InteropServices;
using System.Security;
using System.Globalization; //for CultureInfo
#pragma warning disable 1634, 1691 //disable warnings about unknown pragma
#if WINDOWS_BASE
using MS.Internal.WindowsBase;
#elif PRESENTATION_CORE
using MS.Internal.PresentationCore;
#elif PRESENTATIONFRAMEWORK
using MS.Internal.PresentationFramework;
#elif DRT
using MS.Internal.Drt;
#else
#error Attempt to use FriendAccessAllowedAttribute from an unknown assembly.
using MS.Internal.YourAssemblyName;
#endif
namespace MS.Utility
{
#region TraceProvider
[Guid("748004CA-4959-409a-887C-6546438CF48E")]
[FriendAccessAllowed]
internal class TraceProvider
{
private const ushort _version = 2;
private UnsafeNativeMethods.EtwTrace.EtwProc _etwProc; // Trace Callback function
private SecurityCriticalDataForSet _registrationHandle; // Trace Registration Handle
private ulong _traceHandle; // Trace Logger Handle from callback
private byte _level; // Tracing Level
private uint _flags; // Trace Enable Flags
private bool _enabled; // Enabled flag from Trace callback
///
/// Critical: This calls critical code in TraceProvider (Register)
///
[SecurityCritical]
internal TraceProvider(string _applicationName, Guid controlGuid)
{
_level = 0;
_flags = 0;
_enabled = false;
_traceHandle = 0;
_registrationHandle = new SecurityCriticalDataForSet(0);
// Register the controlGuid with ETW
Register(controlGuid);
}
///
/// Critical: This calls critical code in EtwTrace
/// TreatAsSafe: the registration handle this passes in to UnregisterTraceGuids
/// was generated by the ETW unmanaged API and can't be tampered with from our side
///
[SecurityCritical, SecurityTreatAsSafe]
~TraceProvider()
{
//
// Unregister from ETW using the _registrationHandle saved from
// the register call. We don't care what UnregisterTraceGuids returns.
// If the call fails there's nothing the finalizer can do anyway
//
#pragma warning suppress 6031 //presharp suppression
UnsafeNativeMethods.EtwTrace.UnregisterTraceGuids(_registrationHandle.Value);
GC.KeepAlive(_etwProc);
}
internal uint Flags
{
get
{
return _flags;
}
}
internal byte Level
{
get
{
return _level;
}
}
internal bool IsEnabled
{
get
{
return _enabled;
}
}
//
// This callback function is called by ETW to enable or disable
// Tracing dynamically
//
///
/// Critical: This calls critical code in EtwTrace
/// TreatAsSafe: This callback is called by the ETW unmanaged API when tracing has been enabled.
/// This method does nothing insecure with the data passed into it. The registration of this callback
/// is covered by the Register method
///
[SecurityCritical, SecurityTreatAsSafe]
internal unsafe uint MyCallback(uint requestCode, System.IntPtr context, System.IntPtr bufferSize, byte* byteBuffer)
{
try
{
BaseEvent* buffer = (BaseEvent*)byteBuffer;
switch (requestCode)
{
case RequestCodes.EnableEvents:
_traceHandle = buffer->HistoricalContext;
_flags = (uint)UnsafeNativeMethods.EtwTrace.GetTraceEnableFlags((ulong)buffer->HistoricalContext);
_level = UnsafeNativeMethods.EtwTrace.GetTraceEnableLevel((ulong)buffer->HistoricalContext);
_enabled = true;
break;
case RequestCodes.DisableEvents:
_enabled = false;
_traceHandle = 0;
_level = 0;
_flags = 0;
break;
default:
_enabled = false;
_traceHandle = 0;
break;
}
return 0;
}
catch(Exception e)
{
// PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions.
//
// This should be CriticalExceptions.IsCriticalException, but that requires
// linking to WindowsBase, which is a heavy requirement for "shared" code.
//
if ((e is NullReferenceException) || (e is System.Runtime.InteropServices.SEHException))
{
throw;
}
else
{
return 0;
}
}
}
//
// Registers the controlGuid with an inbuilt callback
//
///
/// Critical: This calls critical code in UnsafeNativeMethods.EtwTrace
/// and sets critical for set field _registrationHandle
///
[SecurityCritical]
private unsafe uint Register(Guid controlGuid)
{
uint status;
ulong registrationHandle;
UnsafeNativeMethods.EtwTrace.TraceGuidRegistration guidReg = new UnsafeNativeMethods.EtwTrace.TraceGuidRegistration();
Guid dummyGuid = new Guid(0xb4955bf0,
0x3af1,
0x4740,
0xb4,0x75,
0x99,0x05,0x5d,0x3f,0xe9,0xaa);
_etwProc = new UnsafeNativeMethods.EtwTrace.EtwProc(MyCallback);
// This dummyGuid is there for ETW backward compat issues
guidReg.Guid = &dummyGuid;
guidReg.RegHandle = null;
status = UnsafeNativeMethods.EtwTrace.RegisterTraceGuids(_etwProc, null, ref controlGuid, 1, ref guidReg, null, null, out registrationHandle);
_registrationHandle.Value = registrationHandle;
return status;
}
// All of the following TraceEvent overloads are used in the codebase. To keep FxCop happy
// we don't keep around unused ones. If another overload is needed it is trivial to add.
// No arguments
internal void TraceEvent(Guid eventGuid, byte eventType)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, null, null);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType)
{
TraceEvent(level, eventGuid, eventType, null, null);
}
// 1 argument
internal void TraceEvent(Guid eventGuid, byte eventType, object data0)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, null);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0)
{
TraceEvent(level, eventGuid, eventType, data0, null);
}
// 2 arguments
internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1)
{
TraceEvent(level, eventGuid, eventType, data0, data1, null, null, null, null, null, null, null);
}
// 3 arguments
internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2)
{
TraceEvent(level, eventGuid, eventType, data0, data1, data2, null, null, null, null, null, null);
}
// 4 arguments
internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2, data3);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3)
{
TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, null, null, null, null, null);
}
// 5 arguments
internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3, object data4)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2, data3, data4);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3, object data4)
{
TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, data4, null, null, null, null);
}
///
/// Critical: This calls critical code in UnsaveNativeMethods.EtwTrace
/// TreatAsSafe: The arguments are serialized and sent to the unmanaged ETW API as a packet with a verified size
/// the unmanaged ETW code stores this in a buffer which is later picked up by post-processing tools - the data cannot
/// be executed
///
[SecurityCritical, SecurityTreatAsSafe]
internal unsafe uint TraceEvent(
EventTrace.Level level, Guid eventGuid, byte evtype,
object data0, object data1, object data2, object data3, object data4, object data5, object data6, object data7, object data8)
{
uint status = 0;
BaseEvent ev; // Takes up 304 bytes on the stack
// The largest possible item stored in this buffer from each of data0
// through data8 will be a decimal (strings are logged as pointers)
const uint bufferSize = sizeof(decimal) * 9;
char* buffer = stackalloc char[(int)bufferSize];
uint offset = 0;
char* ptr = buffer;
string s0, s1, s2, s3, s4, s5, s6, s7, s8;
int stringMask = 0;
uint argCount = 0;
int mofIndex = 0;
s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = "";
ev.ClientContext = 0;
ev.Flags = 0x00120000; // define Constants
ev.Guid = eventGuid;
ev.EventType = evtype;
ev.Level = level;
ev.Version = _version;
MofField* be = null;
if (data0 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
if ((s0 = ProcessOneObject(data0, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000001;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data1 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s1 = ProcessOneObject(data1, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000002;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data2 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s2 = ProcessOneObject(data2, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000004;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data3 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s3 = ProcessOneObject(data3, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000008;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data4 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s4 = ProcessOneObject(data4, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000010;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data5 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s5 = ProcessOneObject(data5, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000020;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data6 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s6 = ProcessOneObject(data6, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000040;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data7 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s7 = ProcessOneObject(data7, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000080;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data8 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s8 = ProcessOneObject(data8, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000100;
mofIndex++; // Leave a slot for the String Pointer
}
}
// Assert we haven't exceeded the buffer size
Invariant.Assert(ptr - buffer <= bufferSize);
// Now pin all the strings and use the stringMask to pass them over through mofField
fixed (char* vptr0 = s0, vptr1 = s1, vptr2 = s2, vptr3 = s3, vptr4 = s4, vptr5 = s5, vptr6 = s6, vptr7 = s7, vptr8 = s8)
{
int i = 0;
if ((stringMask & 0x00000001) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s0.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr0;
}
i++;
if ((stringMask & 0x00000002) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s1.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr1;
}
i++;
if ((stringMask & 0x00000004) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s2.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr2;
}
i++;
if ((stringMask & 0x00000008) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s3.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr3;
}
i++;
if ((stringMask & 0x00000010) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s4.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr4;
}
i++;
if ((stringMask & 0x00000020) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s5.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr5;
}
i++;
if ((stringMask & 0x00000040) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s6.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr6;
}
i++;
if ((stringMask & 0x00000080) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s7.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr7;
}
i++;
if ((stringMask & 0x00000100) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s8.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr8;
}
ev.BufferSize = 48 + (uint)mofIndex * (uint)sizeof(MofField);
status = UnsafeNativeMethods.EtwTrace.TraceEvent(_traceHandle, (char*)&ev);
}
return status;
}
///
///Critical - unsafe pointers
///
[SecurityCritical]
private unsafe string ProcessOneObject(object data, MofField* mofField, char* ptr, ref uint offSet)
{
return EncodeObject(data, mofField, ptr, ref offSet, (byte*)null);
}
//
[SecurityCritical]
private unsafe string EncodeObject(object data, MofField* mofField, char* ptr, ref uint offSet, byte* ptrArgInfo)
{
if (data == null)
{
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)0; //NULL type, WIN64 Changes
*(ushort*)(ptrArgInfo + 1) = (ushort)0;
}
mofField->DataLength = 0;
mofField->DataPointer = (void*)null; //WIN64 Changes (?)
return null;
}
// if the data is an enum we'll convert it to its underlying type
Type dataType = data.GetType();
if (dataType.IsEnum)
{
data = Convert.ChangeType(data, Enum.GetUnderlyingType(dataType), CultureInfo.InvariantCulture);
}
string sRet = data as string;
if (sRet != null)
{
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)2; //WIN64 Changes
*(ushort*)(ptrArgInfo + 1) = (ushort)(sRet.Length < 65535 ? sRet.Length : 65535); //WIN64 Changes
}
else
{ // TraceEvent path. Need counted strings.
mofField->DataLength = sizeof(ushort);
ushort* ushortptr = (ushort*)ptr;
*ushortptr = (ushort)(sRet.Length * 2 < 65535 ? sRet.Length * 2 : 65535);
mofField->DataPointer = (void*)ushortptr;
offSet += sizeof(ushort);
}
return sRet;
}
if (data is sbyte)
{
mofField->DataLength = sizeof(sbyte);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)3; //WIN64 Changes
}
sbyte* sbyteptr = (sbyte*)ptr;
*sbyteptr = (sbyte)data; //WIN64 Changes
mofField->DataPointer = (void*)sbyteptr;
offSet += sizeof(sbyte);
}
else if (data is byte)
{
mofField->DataLength = sizeof(byte);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)4; //WIN64 Changes
}
byte* byteptr = (byte*)ptr;
*byteptr = (byte)data; //WIN64 Changes
mofField->DataPointer = (void*)byteptr;
offSet += sizeof(byte);
}
else if (data is short)
{
mofField->DataLength = sizeof(short);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)5; //WIN64 Changes
}
short* shortptr = (short*)ptr;
*shortptr = (short)data; //WIN64 Changes
mofField->DataPointer = (void*)shortptr;
offSet += sizeof(short);
}
else if (data is ushort)
{
mofField->DataLength = sizeof(ushort);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)6; //WIN64 Changes
}
ushort* ushortptr = (ushort*)ptr;
*ushortptr = (ushort)data; //WIN64 Changes
mofField->DataPointer = (void*)ushortptr;
offSet += sizeof(ushort);
}
else if (data is int)
{
mofField->DataLength = sizeof(int);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)7; //WIN64 Changes
}
int* intptr = (int*)ptr;
*intptr = (int)data; //WIN64 Changes
mofField->DataPointer = (void*)intptr;
offSet += sizeof(int);
}
else if (data is uint)
{
mofField->DataLength = sizeof(uint);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)8; //WIN64 Changes
}
uint* uintptr = (uint*)ptr;
*uintptr = (uint)data; //WIN64 Changes
mofField->DataPointer = (void*)uintptr;
offSet += sizeof(uint);
}
else if (data is long)
{
mofField->DataLength = sizeof(long);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)9; //WIN64 Changes
}
long* longptr = (long*)ptr;
*longptr = (long)data; //WIN64 Changes
mofField->DataPointer = (void*)longptr;
offSet += sizeof(long);
}
else if (data is ulong)
{
mofField->DataLength = sizeof(ulong);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)10; //WIN64 Changes
}
ulong* ulongptr = (ulong*)ptr;
*ulongptr = (ulong)data; //WIN64 Changes
mofField->DataPointer = (void*)ulongptr;
offSet += sizeof(ulong);
}
else if (data is char)
{
mofField->DataLength = sizeof(char);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)11; //WIN64 Changes
}
char* charptr = (char*)ptr;
*charptr = (char)data; //WIN64 Changes
mofField->DataPointer = (void*)charptr;
offSet += sizeof(char);
}
else if (data is float)
{
mofField->DataLength = sizeof(float);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)12; //WIN64 Changes
}
float* floatptr = (float*)ptr;
*floatptr = (float)data; //WIN64 Changes
mofField->DataPointer = (void*)floatptr;
offSet += sizeof(float);
}
else if (data is double)
{
mofField->DataLength = sizeof(double);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)13; //WIN64 Changes
}
double* doubleptr = (double*)ptr;
*doubleptr = (double)data; //WIN64 Changes
mofField->DataPointer = (void*)doubleptr;
offSet += sizeof(double);
}
else if (data is bool)
{
mofField->DataLength = sizeof(bool);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)14; //WIN64 Changes
}
bool* boolptr = (bool*)ptr;
*boolptr = (bool)data; //WIN64 Changes
mofField->DataPointer = (void*)boolptr;
offSet += sizeof(bool);
}
else if (data is decimal)
{
mofField->DataLength = (uint)sizeof(decimal);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)15; //WIN64 Changes
}
decimal* decimalptr = (decimal*)ptr;
*decimalptr = (decimal)data; //WIN64 Changes
mofField->DataPointer = (void*)decimalptr;
offSet += (uint)sizeof(decimal);
}
else
{
//To our eyes, everything else is a just a string
sRet = data.ToString();
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)2; //WIN64 Changes
*(ushort*)(ptrArgInfo + 1) = (ushort)(sRet.Length < 65535 ? sRet.Length : 65535); //WIN64 Changes
}
else
{ // TraceEvent path. Need counted strings.
mofField->DataLength = sizeof(ushort);
ushort* ushortptr = (ushort*)ptr;
*ushortptr = (ushort)(sRet.Length * 2 < 65535 ? sRet.Length * 2 : 65535);
mofField->DataPointer = (void*)ushortptr;
offSet += sizeof(ushort);
}
return sRet;
}
if (ptrArgInfo != null)
{
*(ushort*)(ptrArgInfo + 1) = (ushort)(mofField->DataLength); //WIN64 Changes (?)
}
return sRet;
}
//
// Enumerations
//
internal sealed class RequestCodes
{
// Ensure class cannot be instantiated
private RequestCodes() { }
internal const uint GetAllData = 0; // Never Used
internal const uint GetSingleInstance = 1; // Never Used
internal const uint SetSingleInstance = 2; // Never Used
internal const uint SetSingleItem = 3; // Never Used
internal const uint EnableEvents = 4; // Enable Tracing
internal const uint DisableEvents = 5; // Disable Tracing
internal const uint EnableCollection = 6; // Never Used
internal const uint DisableCollection = 7; // Never Used
internal const uint RegInfo = 8; // Registration Information
internal const uint ExecuteMethod = 9; // Never Used
}
//
// Structures
//
[StructLayout(LayoutKind.Explicit, Size = 16)]
internal struct MofField
{
[FieldOffset(0)]
internal unsafe void* DataPointer;
[FieldOffset(8)]
internal uint DataLength;
[FieldOffset(12)]
internal uint DataType;
}
[StructLayout(LayoutKind.Explicit, Size = 304)]
internal struct BaseEvent
{
[FieldOffset(0)]
internal uint BufferSize;
[FieldOffset(4)]
internal byte EventType; // EventType.xx constant or a custom event subtype
[FieldOffset(5)]
internal EventTrace.Level Level;
[FieldOffset(6)]
internal ushort Version;
[FieldOffset(8)]
internal ulong HistoricalContext;
[FieldOffset(16)]
internal Int64 TimeStamp;
[FieldOffset(24)]
internal System.Guid Guid;
[FieldOffset(40)]
internal uint ClientContext;
[FieldOffset(44)]
internal uint Flags;
[FieldOffset(48)]
internal MofField UserData; // We have allocated enough space for 16 MOF_FIELD structures at the bottom
}
}
#endregion //TraceProvider
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
// File: TraceProvider
//
// A Managed wrapper for Event Tracing for Windows
// Based on TraceEvent.cs found in nt\base\wmi\trace.net
// Provides an internal Avalon API to replace Microsoft.Windows.EventTracing.dll
//
//---------------------------------------------------------------------------
using System;
using MS.Win32;
using MS.Internal;
using System.Runtime.InteropServices;
using System.Security;
using System.Globalization; //for CultureInfo
#pragma warning disable 1634, 1691 //disable warnings about unknown pragma
#if WINDOWS_BASE
using MS.Internal.WindowsBase;
#elif PRESENTATION_CORE
using MS.Internal.PresentationCore;
#elif PRESENTATIONFRAMEWORK
using MS.Internal.PresentationFramework;
#elif DRT
using MS.Internal.Drt;
#else
#error Attempt to use FriendAccessAllowedAttribute from an unknown assembly.
using MS.Internal.YourAssemblyName;
#endif
namespace MS.Utility
{
#region TraceProvider
[Guid("748004CA-4959-409a-887C-6546438CF48E")]
[FriendAccessAllowed]
internal class TraceProvider
{
private const ushort _version = 2;
private UnsafeNativeMethods.EtwTrace.EtwProc _etwProc; // Trace Callback function
private SecurityCriticalDataForSet _registrationHandle; // Trace Registration Handle
private ulong _traceHandle; // Trace Logger Handle from callback
private byte _level; // Tracing Level
private uint _flags; // Trace Enable Flags
private bool _enabled; // Enabled flag from Trace callback
///
/// Critical: This calls critical code in TraceProvider (Register)
///
[SecurityCritical]
internal TraceProvider(string _applicationName, Guid controlGuid)
{
_level = 0;
_flags = 0;
_enabled = false;
_traceHandle = 0;
_registrationHandle = new SecurityCriticalDataForSet(0);
// Register the controlGuid with ETW
Register(controlGuid);
}
///
/// Critical: This calls critical code in EtwTrace
/// TreatAsSafe: the registration handle this passes in to UnregisterTraceGuids
/// was generated by the ETW unmanaged API and can't be tampered with from our side
///
[SecurityCritical, SecurityTreatAsSafe]
~TraceProvider()
{
//
// Unregister from ETW using the _registrationHandle saved from
// the register call. We don't care what UnregisterTraceGuids returns.
// If the call fails there's nothing the finalizer can do anyway
//
#pragma warning suppress 6031 //presharp suppression
UnsafeNativeMethods.EtwTrace.UnregisterTraceGuids(_registrationHandle.Value);
GC.KeepAlive(_etwProc);
}
internal uint Flags
{
get
{
return _flags;
}
}
internal byte Level
{
get
{
return _level;
}
}
internal bool IsEnabled
{
get
{
return _enabled;
}
}
//
// This callback function is called by ETW to enable or disable
// Tracing dynamically
//
///
/// Critical: This calls critical code in EtwTrace
/// TreatAsSafe: This callback is called by the ETW unmanaged API when tracing has been enabled.
/// This method does nothing insecure with the data passed into it. The registration of this callback
/// is covered by the Register method
///
[SecurityCritical, SecurityTreatAsSafe]
internal unsafe uint MyCallback(uint requestCode, System.IntPtr context, System.IntPtr bufferSize, byte* byteBuffer)
{
try
{
BaseEvent* buffer = (BaseEvent*)byteBuffer;
switch (requestCode)
{
case RequestCodes.EnableEvents:
_traceHandle = buffer->HistoricalContext;
_flags = (uint)UnsafeNativeMethods.EtwTrace.GetTraceEnableFlags((ulong)buffer->HistoricalContext);
_level = UnsafeNativeMethods.EtwTrace.GetTraceEnableLevel((ulong)buffer->HistoricalContext);
_enabled = true;
break;
case RequestCodes.DisableEvents:
_enabled = false;
_traceHandle = 0;
_level = 0;
_flags = 0;
break;
default:
_enabled = false;
_traceHandle = 0;
break;
}
return 0;
}
catch(Exception e)
{
// PreSharp Complaint 6500 - do not handle null-ref or SEH exceptions.
//
// This should be CriticalExceptions.IsCriticalException, but that requires
// linking to WindowsBase, which is a heavy requirement for "shared" code.
//
if ((e is NullReferenceException) || (e is System.Runtime.InteropServices.SEHException))
{
throw;
}
else
{
return 0;
}
}
}
//
// Registers the controlGuid with an inbuilt callback
//
///
/// Critical: This calls critical code in UnsafeNativeMethods.EtwTrace
/// and sets critical for set field _registrationHandle
///
[SecurityCritical]
private unsafe uint Register(Guid controlGuid)
{
uint status;
ulong registrationHandle;
UnsafeNativeMethods.EtwTrace.TraceGuidRegistration guidReg = new UnsafeNativeMethods.EtwTrace.TraceGuidRegistration();
Guid dummyGuid = new Guid(0xb4955bf0,
0x3af1,
0x4740,
0xb4,0x75,
0x99,0x05,0x5d,0x3f,0xe9,0xaa);
_etwProc = new UnsafeNativeMethods.EtwTrace.EtwProc(MyCallback);
// This dummyGuid is there for ETW backward compat issues
guidReg.Guid = &dummyGuid;
guidReg.RegHandle = null;
status = UnsafeNativeMethods.EtwTrace.RegisterTraceGuids(_etwProc, null, ref controlGuid, 1, ref guidReg, null, null, out registrationHandle);
_registrationHandle.Value = registrationHandle;
return status;
}
// All of the following TraceEvent overloads are used in the codebase. To keep FxCop happy
// we don't keep around unused ones. If another overload is needed it is trivial to add.
// No arguments
internal void TraceEvent(Guid eventGuid, byte eventType)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, null, null);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType)
{
TraceEvent(level, eventGuid, eventType, null, null);
}
// 1 argument
internal void TraceEvent(Guid eventGuid, byte eventType, object data0)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, null);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0)
{
TraceEvent(level, eventGuid, eventType, data0, null);
}
// 2 arguments
internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1)
{
TraceEvent(level, eventGuid, eventType, data0, data1, null, null, null, null, null, null, null);
}
// 3 arguments
internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2)
{
TraceEvent(level, eventGuid, eventType, data0, data1, data2, null, null, null, null, null, null);
}
// 4 arguments
internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2, data3);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3)
{
TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, null, null, null, null, null);
}
// 5 arguments
internal void TraceEvent(Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3, object data4)
{
TraceEvent(EventTrace.Level.normal, eventGuid, eventType, data0, data1, data2, data3, data4);
}
internal void TraceEvent(EventTrace.Level level, Guid eventGuid, byte eventType, object data0, object data1, object data2, object data3, object data4)
{
TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, data4, null, null, null, null);
}
///
/// Critical: This calls critical code in UnsaveNativeMethods.EtwTrace
/// TreatAsSafe: The arguments are serialized and sent to the unmanaged ETW API as a packet with a verified size
/// the unmanaged ETW code stores this in a buffer which is later picked up by post-processing tools - the data cannot
/// be executed
///
[SecurityCritical, SecurityTreatAsSafe]
internal unsafe uint TraceEvent(
EventTrace.Level level, Guid eventGuid, byte evtype,
object data0, object data1, object data2, object data3, object data4, object data5, object data6, object data7, object data8)
{
uint status = 0;
BaseEvent ev; // Takes up 304 bytes on the stack
// The largest possible item stored in this buffer from each of data0
// through data8 will be a decimal (strings are logged as pointers)
const uint bufferSize = sizeof(decimal) * 9;
char* buffer = stackalloc char[(int)bufferSize];
uint offset = 0;
char* ptr = buffer;
string s0, s1, s2, s3, s4, s5, s6, s7, s8;
int stringMask = 0;
uint argCount = 0;
int mofIndex = 0;
s0 = s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = "";
ev.ClientContext = 0;
ev.Flags = 0x00120000; // define Constants
ev.Guid = eventGuid;
ev.EventType = evtype;
ev.Level = level;
ev.Version = _version;
MofField* be = null;
if (data0 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
if ((s0 = ProcessOneObject(data0, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000001;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data1 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s1 = ProcessOneObject(data1, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000002;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data2 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s2 = ProcessOneObject(data2, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000004;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data3 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s3 = ProcessOneObject(data3, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000008;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data4 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s4 = ProcessOneObject(data4, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000010;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data5 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s5 = ProcessOneObject(data5, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000020;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data6 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s6 = ProcessOneObject(data6, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000040;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data7 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s7 = ProcessOneObject(data7, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000080;
mofIndex++; // Leave a slot for the String Pointer
}
}
if (data8 != null)
{
argCount++;
be = &(&ev.UserData)[mofIndex++];
ptr = buffer + offset;
if ((s8 = ProcessOneObject(data8, be, ptr, ref offset)) != null)
{
stringMask |= 0x00000100;
mofIndex++; // Leave a slot for the String Pointer
}
}
// Assert we haven't exceeded the buffer size
Invariant.Assert(ptr - buffer <= bufferSize);
// Now pin all the strings and use the stringMask to pass them over through mofField
fixed (char* vptr0 = s0, vptr1 = s1, vptr2 = s2, vptr3 = s3, vptr4 = s4, vptr5 = s5, vptr6 = s6, vptr7 = s7, vptr8 = s8)
{
int i = 0;
if ((stringMask & 0x00000001) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s0.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr0;
}
i++;
if ((stringMask & 0x00000002) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s1.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr1;
}
i++;
if ((stringMask & 0x00000004) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s2.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr2;
}
i++;
if ((stringMask & 0x00000008) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s3.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr3;
}
i++;
if ((stringMask & 0x00000010) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s4.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr4;
}
i++;
if ((stringMask & 0x00000020) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s5.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr5;
}
i++;
if ((stringMask & 0x00000040) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s6.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr6;
}
i++;
if ((stringMask & 0x00000080) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s7.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr7;
}
i++;
if ((stringMask & 0x00000100) != 0)
{
i++;
(&ev.UserData)[i].DataLength = (uint)s8.Length * 2;
(&ev.UserData)[i].DataPointer = (void*)vptr8;
}
ev.BufferSize = 48 + (uint)mofIndex * (uint)sizeof(MofField);
status = UnsafeNativeMethods.EtwTrace.TraceEvent(_traceHandle, (char*)&ev);
}
return status;
}
///
///Critical - unsafe pointers
///
[SecurityCritical]
private unsafe string ProcessOneObject(object data, MofField* mofField, char* ptr, ref uint offSet)
{
return EncodeObject(data, mofField, ptr, ref offSet, (byte*)null);
}
//
[SecurityCritical]
private unsafe string EncodeObject(object data, MofField* mofField, char* ptr, ref uint offSet, byte* ptrArgInfo)
{
if (data == null)
{
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)0; //NULL type, WIN64 Changes
*(ushort*)(ptrArgInfo + 1) = (ushort)0;
}
mofField->DataLength = 0;
mofField->DataPointer = (void*)null; //WIN64 Changes (?)
return null;
}
// if the data is an enum we'll convert it to its underlying type
Type dataType = data.GetType();
if (dataType.IsEnum)
{
data = Convert.ChangeType(data, Enum.GetUnderlyingType(dataType), CultureInfo.InvariantCulture);
}
string sRet = data as string;
if (sRet != null)
{
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)2; //WIN64 Changes
*(ushort*)(ptrArgInfo + 1) = (ushort)(sRet.Length < 65535 ? sRet.Length : 65535); //WIN64 Changes
}
else
{ // TraceEvent path. Need counted strings.
mofField->DataLength = sizeof(ushort);
ushort* ushortptr = (ushort*)ptr;
*ushortptr = (ushort)(sRet.Length * 2 < 65535 ? sRet.Length * 2 : 65535);
mofField->DataPointer = (void*)ushortptr;
offSet += sizeof(ushort);
}
return sRet;
}
if (data is sbyte)
{
mofField->DataLength = sizeof(sbyte);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)3; //WIN64 Changes
}
sbyte* sbyteptr = (sbyte*)ptr;
*sbyteptr = (sbyte)data; //WIN64 Changes
mofField->DataPointer = (void*)sbyteptr;
offSet += sizeof(sbyte);
}
else if (data is byte)
{
mofField->DataLength = sizeof(byte);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)4; //WIN64 Changes
}
byte* byteptr = (byte*)ptr;
*byteptr = (byte)data; //WIN64 Changes
mofField->DataPointer = (void*)byteptr;
offSet += sizeof(byte);
}
else if (data is short)
{
mofField->DataLength = sizeof(short);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)5; //WIN64 Changes
}
short* shortptr = (short*)ptr;
*shortptr = (short)data; //WIN64 Changes
mofField->DataPointer = (void*)shortptr;
offSet += sizeof(short);
}
else if (data is ushort)
{
mofField->DataLength = sizeof(ushort);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)6; //WIN64 Changes
}
ushort* ushortptr = (ushort*)ptr;
*ushortptr = (ushort)data; //WIN64 Changes
mofField->DataPointer = (void*)ushortptr;
offSet += sizeof(ushort);
}
else if (data is int)
{
mofField->DataLength = sizeof(int);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)7; //WIN64 Changes
}
int* intptr = (int*)ptr;
*intptr = (int)data; //WIN64 Changes
mofField->DataPointer = (void*)intptr;
offSet += sizeof(int);
}
else if (data is uint)
{
mofField->DataLength = sizeof(uint);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)8; //WIN64 Changes
}
uint* uintptr = (uint*)ptr;
*uintptr = (uint)data; //WIN64 Changes
mofField->DataPointer = (void*)uintptr;
offSet += sizeof(uint);
}
else if (data is long)
{
mofField->DataLength = sizeof(long);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)9; //WIN64 Changes
}
long* longptr = (long*)ptr;
*longptr = (long)data; //WIN64 Changes
mofField->DataPointer = (void*)longptr;
offSet += sizeof(long);
}
else if (data is ulong)
{
mofField->DataLength = sizeof(ulong);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)10; //WIN64 Changes
}
ulong* ulongptr = (ulong*)ptr;
*ulongptr = (ulong)data; //WIN64 Changes
mofField->DataPointer = (void*)ulongptr;
offSet += sizeof(ulong);
}
else if (data is char)
{
mofField->DataLength = sizeof(char);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)11; //WIN64 Changes
}
char* charptr = (char*)ptr;
*charptr = (char)data; //WIN64 Changes
mofField->DataPointer = (void*)charptr;
offSet += sizeof(char);
}
else if (data is float)
{
mofField->DataLength = sizeof(float);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)12; //WIN64 Changes
}
float* floatptr = (float*)ptr;
*floatptr = (float)data; //WIN64 Changes
mofField->DataPointer = (void*)floatptr;
offSet += sizeof(float);
}
else if (data is double)
{
mofField->DataLength = sizeof(double);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)13; //WIN64 Changes
}
double* doubleptr = (double*)ptr;
*doubleptr = (double)data; //WIN64 Changes
mofField->DataPointer = (void*)doubleptr;
offSet += sizeof(double);
}
else if (data is bool)
{
mofField->DataLength = sizeof(bool);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)14; //WIN64 Changes
}
bool* boolptr = (bool*)ptr;
*boolptr = (bool)data; //WIN64 Changes
mofField->DataPointer = (void*)boolptr;
offSet += sizeof(bool);
}
else if (data is decimal)
{
mofField->DataLength = (uint)sizeof(decimal);
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)15; //WIN64 Changes
}
decimal* decimalptr = (decimal*)ptr;
*decimalptr = (decimal)data; //WIN64 Changes
mofField->DataPointer = (void*)decimalptr;
offSet += (uint)sizeof(decimal);
}
else
{
//To our eyes, everything else is a just a string
sRet = data.ToString();
if (ptrArgInfo != null)
{
*ptrArgInfo = (byte)2; //WIN64 Changes
*(ushort*)(ptrArgInfo + 1) = (ushort)(sRet.Length < 65535 ? sRet.Length : 65535); //WIN64 Changes
}
else
{ // TraceEvent path. Need counted strings.
mofField->DataLength = sizeof(ushort);
ushort* ushortptr = (ushort*)ptr;
*ushortptr = (ushort)(sRet.Length * 2 < 65535 ? sRet.Length * 2 : 65535);
mofField->DataPointer = (void*)ushortptr;
offSet += sizeof(ushort);
}
return sRet;
}
if (ptrArgInfo != null)
{
*(ushort*)(ptrArgInfo + 1) = (ushort)(mofField->DataLength); //WIN64 Changes (?)
}
return sRet;
}
//
// Enumerations
//
internal sealed class RequestCodes
{
// Ensure class cannot be instantiated
private RequestCodes() { }
internal const uint GetAllData = 0; // Never Used
internal const uint GetSingleInstance = 1; // Never Used
internal const uint SetSingleInstance = 2; // Never Used
internal const uint SetSingleItem = 3; // Never Used
internal const uint EnableEvents = 4; // Enable Tracing
internal const uint DisableEvents = 5; // Disable Tracing
internal const uint EnableCollection = 6; // Never Used
internal const uint DisableCollection = 7; // Never Used
internal const uint RegInfo = 8; // Registration Information
internal const uint ExecuteMethod = 9; // Never Used
}
//
// Structures
//
[StructLayout(LayoutKind.Explicit, Size = 16)]
internal struct MofField
{
[FieldOffset(0)]
internal unsafe void* DataPointer;
[FieldOffset(8)]
internal uint DataLength;
[FieldOffset(12)]
internal uint DataType;
}
[StructLayout(LayoutKind.Explicit, Size = 304)]
internal struct BaseEvent
{
[FieldOffset(0)]
internal uint BufferSize;
[FieldOffset(4)]
internal byte EventType; // EventType.xx constant or a custom event subtype
[FieldOffset(5)]
internal EventTrace.Level Level;
[FieldOffset(6)]
internal ushort Version;
[FieldOffset(8)]
internal ulong HistoricalContext;
[FieldOffset(16)]
internal Int64 TimeStamp;
[FieldOffset(24)]
internal System.Guid Guid;
[FieldOffset(40)]
internal uint ClientContext;
[FieldOffset(44)]
internal uint Flags;
[FieldOffset(48)]
internal MofField UserData; // We have allocated enough space for 16 MOF_FIELD structures at the bottom
}
}
#endregion //TraceProvider
}
// 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
- CriticalHandle.cs
- SerializationException.cs
- SpanIndex.cs
- CustomValidator.cs
- ToolboxItem.cs
- WebControlsSection.cs
- CounterCreationDataCollection.cs
- HierarchicalDataTemplate.cs
- Base64Stream.cs
- DataGridPagingPage.cs
- RequestQueryProcessor.cs
- ToolboxItemCollection.cs
- DetailsViewRowCollection.cs
- AppearanceEditorPart.cs
- Column.cs
- Size3D.cs
- SqlCrossApplyToCrossJoin.cs
- HyperLinkField.cs
- UnmanagedMarshal.cs
- M3DUtil.cs
- BrushConverter.cs
- DirectoryInfo.cs
- AssemblyNameProxy.cs
- UITypeEditor.cs
- xmlsaver.cs
- SqlClientFactory.cs
- WebHttpBehavior.cs
- ArgumentOutOfRangeException.cs
- HttpGetServerProtocol.cs
- ConfigViewGenerator.cs
- DLinqColumnProvider.cs
- Rect3D.cs
- ChtmlPageAdapter.cs
- WebPartAuthorizationEventArgs.cs
- DetailsViewDeletedEventArgs.cs
- AxWrapperGen.cs
- WorkflowMarkupSerializationProvider.cs
- CurrentChangingEventArgs.cs
- ObjectAssociationEndMapping.cs
- ChannelPoolSettings.cs
- CacheAxisQuery.cs
- SecurityHeaderLayout.cs
- sortedlist.cs
- DataGridViewRowHeaderCell.cs
- DomNameTable.cs
- DBConcurrencyException.cs
- TypeDelegator.cs
- EncodingFallbackAwareXmlTextWriter.cs
- XmlExpressionDumper.cs
- Soap12ServerProtocol.cs
- CircleHotSpot.cs
- GlyphsSerializer.cs
- XmlSchemaRedefine.cs
- GroupBoxRenderer.cs
- SocketException.cs
- ToolStripItemClickedEventArgs.cs
- DataObjectMethodAttribute.cs
- TimeBoundedCache.cs
- StyleCollection.cs
- BitmapFrame.cs
- UnsafeNativeMethodsMilCoreApi.cs
- WebPartDeleteVerb.cs
- ApplicationException.cs
- WebPartConnectionsConnectVerb.cs
- ListViewInsertedEventArgs.cs
- ProcessHostFactoryHelper.cs
- StronglyTypedResourceBuilder.cs
- Repeater.cs
- RuleInfoComparer.cs
- Point3DCollection.cs
- CodeValidator.cs
- PagedDataSource.cs
- ToolStripRenderEventArgs.cs
- StyleTypedPropertyAttribute.cs
- SocketInformation.cs
- HttpEncoder.cs
- DPCustomTypeDescriptor.cs
- EventLogPermission.cs
- HttpHandlerActionCollection.cs
- Camera.cs
- MulticastDelegate.cs
- ProxyWebPart.cs
- Input.cs
- SystemInfo.cs
- Animatable.cs
- AxisAngleRotation3D.cs
- FixedTextContainer.cs
- TypeBuilderInstantiation.cs
- OdbcReferenceCollection.cs
- FilteredAttributeCollection.cs
- HttpRequestCacheValidator.cs
- ContextTokenTypeConverter.cs
- UserControlCodeDomTreeGenerator.cs
- NamespaceDecl.cs
- FactoryMaker.cs
- FontResourceCache.cs
- CatalogZone.cs
- SizeF.cs
- OutputCacheEntry.cs
- Parallel.cs