Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Services / Monitoring / system / Diagnosticts / EventLogEntry.cs / 1 / EventLogEntry.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Diagnostics {
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.ComponentModel;
using System.Diagnostics;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System;
using System.Security;
using System.Security.Permissions;
using System.IO;
using System.Globalization;
using System.Runtime.Versioning;
///
///
///
/// encapsulates a single record in the NT event log.
///
///
[
ToolboxItem(false),
DesignTimeVisible(false),
Serializable,
]
public sealed class EventLogEntry : Component, ISerializable {
internal byte[] dataBuf;
internal int bufOffset;
private EventLog owner;
private string category;
private string message;
// make sure only others in this package can create us
internal EventLogEntry(byte[] buf, int offset, EventLog log) {
this.dataBuf = buf;
this.bufOffset = offset;
this.owner = log;
GC.SuppressFinalize(this);
}
///
///
///
private EventLogEntry(SerializationInfo info, StreamingContext context) {
dataBuf = (byte[])info.GetValue("DataBuffer", typeof(byte[]));
string logName = info.GetString("LogName");
string machineName = info.GetString("MachineName");
owner = new EventLog(logName, machineName, "");
GC.SuppressFinalize(this);
}
///
///
/// Gets the name of the computer on which this entry was generated.
///
///
///
[MonitoringDescription(SR.LogEntryMachineName)]
public string MachineName {
get {
// first skip over the source name
int pos = bufOffset + FieldOffsets.RAWDATA;
while (CharFrom(dataBuf, pos) != '\0')
pos += 2;
pos += 2;
char ch = CharFrom(dataBuf, pos);
StringBuilder buf = new StringBuilder();
while (ch != '\0') {
buf.Append(ch);
pos += 2;
ch = CharFrom(dataBuf, pos);
}
return buf.ToString();
}
}
///
///
/// Gets the binary data associated with the entry.
///
///
///
[
MonitoringDescription(SR.LogEntryData)
]
public byte[] Data {
get {
int dataLen = IntFrom(dataBuf, bufOffset + FieldOffsets.DATALENGTH);
byte[] data = new byte[dataLen];
Array.Copy(dataBuf, bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.DATAOFFSET),
data, 0, dataLen);
return data;
}
}
/*
///
///
/// Copies the binary data in the member into an
/// array.
///
///
///
///
/// An array of type .
///
///
///
public Byte[] getDataBytes() {
Byte[] data = new Byte[rec.dataLength];
for (int i = 0; i < data.Length; i++)
data[i] = new Byte(rec.buf[i]);
return data;
}
*/
///
///
/// Gets the index of this entry in the event
/// log.
///
///
[MonitoringDescription(SR.LogEntryIndex)]
public int Index {
get {
return IntFrom(dataBuf, bufOffset + FieldOffsets.RECORDNUMBER);
}
}
///
///
/// Gets the text associated with the for this entry.
///
///
///
[MonitoringDescription(SR.LogEntryCategory)]
public string Category {
get {
if (category == null) {
string dllName = GetMessageLibraryNames("CategoryMessageFile");
string cat = owner.FormatMessageWrapper(dllName, (uint) CategoryNumber, null);
if (cat == null)
category = "(" + CategoryNumber.ToString(CultureInfo.CurrentCulture) + ")";
else
category = cat;
}
return category;
}
}
///
///
/// Gets the application-specific category number for this entry
///
///
///
[
MonitoringDescription(SR.LogEntryCategoryNumber)
]
public short CategoryNumber {
get {
return ShortFrom(dataBuf, bufOffset + FieldOffsets.EVENTCATEGORY);
}
}
///
///
/// Gets the application-specific event indentifier of this entry.
///
///
///
[
MonitoringDescription(SR.LogEntryEventID),
Obsolete("This property has been deprecated. Please use System.Diagnostics.EventLogEntry.InstanceId instead. http://go.microsoft.com/fwlink/?linkid=14202")
]
public int EventID {
get {
// Apparently the top 2 bits of this number are not
// always 0. Strip them so the number looks nice to the user.
// The problem is, if the user were to want to call FormatMessage(),
// they'd need these two bits.
return IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID) & 0x3FFFFFFF;
}
}
///
///
///
/// Gets the type
/// of this entry.
///
///
///
[MonitoringDescription(SR.LogEntryEntryType)]
public EventLogEntryType EntryType {
get {
return(EventLogEntryType) ShortFrom(dataBuf, bufOffset + FieldOffsets.EVENTTYPE);
}
}
///
///
/// Gets the localized message corresponding to this event entry.
///
///
///
[
MonitoringDescription(SR.LogEntryMessage),
Editor("System.ComponentModel.Design.BinaryEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing)
]
public string Message {
get {
if (message == null) {
string dllNames = GetMessageLibraryNames("EventMessageFile");
int msgId = IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID);
string msg = owner.FormatMessageWrapper(dllNames, (uint)msgId, ReplacementStrings);
if (msg == null) {
StringBuilder msgBuf = new StringBuilder(SR.GetString(SR.MessageNotFormatted, msgId, Source));
string[] strings = ReplacementStrings;
for (int i = 0; i < strings.Length; i++) {
if (i != 0)
msgBuf.Append(", ");
msgBuf.Append("'");
msgBuf.Append(strings[i]);
msgBuf.Append("'");
}
msg = msgBuf.ToString();
}
else
msg = ReplaceMessageParameters( msg, ReplacementStrings );
message = msg;
}
return message;
}
}
///
///
/// Gets the name of the application that generated this event.
///
///
[MonitoringDescription(SR.LogEntrySource)]
public string Source {
get {
StringBuilder buf = new StringBuilder();
int pos = bufOffset + FieldOffsets.RAWDATA;
char ch = CharFrom(dataBuf, pos);
while (ch != '\0') {
buf.Append(ch);
pos += 2;
ch = CharFrom(dataBuf, pos);
}
return buf.ToString();
}
}
///
///
/// Gets the replacement strings
/// associated with the entry.
///
///
///
[MonitoringDescription(SR.LogEntryReplacementStrings)]
public string[] ReplacementStrings {
get {
string[] strings = new string[ShortFrom(dataBuf, bufOffset + FieldOffsets.NUMSTRINGS)];
int i = 0;
int bufpos = bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.STRINGOFFSET);
StringBuilder buf = new StringBuilder();
while (i < strings.Length) {
char ch = CharFrom(dataBuf, bufpos);
if (ch != '\0')
buf.Append(ch);
else {
strings[i] = buf.ToString();
i++;
buf = new StringBuilder();
}
bufpos += 2;
}
return strings;
}
}
[
MonitoringDescription(SR.LogEntryResourceId),
ComVisible(false)
]
public Int64 InstanceId {
get {
return (UInt32)IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID);
}
}
#if false
internal string StringsBuffer {
get {
StringBuilder buf = new StringBuilder();
int bufpos = bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.STRINGOFFSET);
int i = 0;
int numStrings = ShortFrom(dataBuf, bufOffset + FieldOffsets.NUMSTRINGS);
while (i < numStrings) {
char ch = CharFrom(dataBuf, bufpos);
buf.Append(ch);
bufpos += 2;
if (ch == '\0')
i++;
}
return buf.ToString();
}
}
#endif
///
///
/// Gets the time at which this event was generated, in local time.
///
///
///
[MonitoringDescription(SR.LogEntryTimeGenerated)]
public DateTime TimeGenerated {
get {
return beginningOfTime.AddSeconds(IntFrom(dataBuf, bufOffset + FieldOffsets.TIMEGENERATED)).ToLocalTime();
}
}
///
///
/// Gets
/// the time at which this event was written to the log, in local time.
///
///
///
[MonitoringDescription(SR.LogEntryTimeWritten)]
public DateTime TimeWritten {
get {
return beginningOfTime.AddSeconds(IntFrom(dataBuf, bufOffset + FieldOffsets.TIMEWRITTEN)).ToLocalTime();
}
}
///
///
/// Gets the name
/// of the user responsible for this event.
///
///
[MonitoringDescription(SR.LogEntryUserName)]
public string UserName {
get {
int sidLen = IntFrom(dataBuf, bufOffset + FieldOffsets.USERSIDLENGTH);
if (sidLen == 0)
return null;
byte[] sid = new byte[sidLen];
Array.Copy(dataBuf, bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.USERSIDOFFSET),
sid, 0, sid.Length);
int[] nameUse = new int[1];
char[] name = new char[1024];
char[] refDomName = new char[1024];
int[] nameLen = new int[] {1024};
int[] refDomNameLen = new int[] {1024};
bool success = UnsafeNativeMethods.LookupAccountSid(MachineName, sid, name, nameLen, refDomName, refDomNameLen, nameUse);
if (!success) {
return "";
// NOTE, [....]: it would be nice to return error info, but the only right way to do that
// is to throw an exception. People don't want exceptions thrown in the property though.
#if false
if (Marshal.GetLastWin32Error() == ERROR_NONE_MAPPED)
// There are some SIDs (evidently rare) that are legitimate SIDs but don't
// have a mapping to a name.
return "";
else
throw new InvalidOperationException(SR.GetString(SR.NoAccountInfo), SharedUtils.CreateSafeWin32Exception());
#endif
}
StringBuilder username = new StringBuilder();
username.Append(refDomName, 0, refDomNameLen[0]);
username.Append("\\");
username.Append(name, 0, nameLen[0]);
return username.ToString();
}
}
private char CharFrom(byte[] buf, int offset) {
return(char) ShortFrom(buf, offset);
}
///
///
/// Performs a comparison between two event log entries.
///
///
///
public bool Equals(EventLogEntry otherEntry) {
if (otherEntry == null)
return false;
int ourLen = IntFrom(dataBuf, bufOffset + FieldOffsets.LENGTH);
int theirLen = IntFrom(otherEntry.dataBuf, otherEntry.bufOffset + FieldOffsets.LENGTH);
if (ourLen != theirLen) {
return false;
}
int min = bufOffset;
int max = bufOffset + ourLen;
int j = otherEntry.bufOffset;
for (int i = min; i < max; i++, j++)
if (dataBuf[i] != otherEntry.dataBuf[j]) {
return false;
}
return true;
}
private int IntFrom(byte[] buf, int offset) {
// assumes Little Endian byte order.
return(unchecked((int)0xFF000000) & (buf[offset+3] << 24)) | (0xFF0000 & (buf[offset+2] << 16)) |
(0xFF00 & (buf[offset+1] << 8)) | (0xFF & (buf[offset]));
}
// Replacing parameters '%n' in formated message using 'ParameterMessageFile' registry key.
internal string ReplaceMessageParameters( String msg, string[] insertionStrings ) {
int percentIdx = msg.IndexOf('%');
if ( percentIdx < 0 )
return msg; // no '%' at all
int startCopyIdx = 0; // start idx of last [....] msg chars to copy
int msgLength = msg.Length;
StringBuilder buf = new StringBuilder();
string paramDLLNames = GetMessageLibraryNames("ParameterMessageFile");
while ( percentIdx >= 0 ) {
string param = null;
// Convert numeric string after '%' to paramMsgID number.
int lasNumIdx = percentIdx + 1;
while ( lasNumIdx < msgLength && Char.IsDigit(msg, lasNumIdx) )
lasNumIdx++;
uint paramMsgID = 0;
// If we can't parse it, leave the paramMsgID as zero. We'll skip the replacement and just put
// the %xxxx into the final message.
if (lasNumIdx != percentIdx + 1 )
UInt32.TryParse( msg.Substring(percentIdx + 1, lasNumIdx - percentIdx - 1), out paramMsgID);
if ( paramMsgID != 0 )
param = owner.FormatMessageWrapper( paramDLLNames, paramMsgID, insertionStrings);
if ( param != null ) {
if ( percentIdx > startCopyIdx )
buf.Append(msg, startCopyIdx, percentIdx - startCopyIdx); // original chars from msg
buf.Append(param);
startCopyIdx = lasNumIdx;
}
percentIdx = msg.IndexOf('%', percentIdx + 1);
}
if ( msgLength - startCopyIdx > 0 )
buf.Append(msg, startCopyIdx, msgLength - startCopyIdx); // last span of original msg
return buf.ToString();
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
private static RegistryKey GetSourceRegKey(string logName, string source, string machineName) {
RegistryKey eventKey = null;
RegistryKey logKey = null;
try {
eventKey = EventLog.GetEventLogRegKey(machineName, false);
if (eventKey == null)
return null;
if (logName == null)
logKey = eventKey.OpenSubKey("Application", /*writable*/false);
else
logKey = eventKey.OpenSubKey(logName, /*writable*/false);
if (logKey == null)
return null;
return logKey.OpenSubKey(source, /*writable*/false);
}
finally {
if (eventKey != null) eventKey.Close();
if (logKey != null) logKey.Close();
}
}
// -----------------------------------------------------------------------------
// Returns DLL names list.
// libRegKey can be: "EventMessageFile", "CategoryMessageFile", "ParameterMessageFile"
private string GetMessageLibraryNames(string libRegKey ) {
// get the value stored in the registry
string fileName = null;
RegistryKey regKey = null;
try {
regKey = GetSourceRegKey(owner.Log, Source, owner.MachineName);
if (regKey != null) {
if (owner.MachineName == ".")
fileName = (string)regKey.GetValue(libRegKey);
else
fileName = (string)regKey.GetValue(libRegKey, null, RegistryValueOptions.DoNotExpandEnvironmentNames);
}
}
finally {
if (regKey != null)
regKey.Close();
}
if (fileName == null)
return null;
// convert any environment variables to their current values
// (the key might have something like %systemroot% in it.)
// if we're looking at a remote machine, just try to replace %systemroot% at the beginning
if (owner.MachineName != ".") {
if (fileName.EndsWith(EventLog.DllName, StringComparison.Ordinal)) {
// if it's our EventLogMessages.dll, just use the local copy
return EventLog.GetDllPath(".");
}
else if (String.Compare(fileName, 0, "%systemroot%", 0, 12, StringComparison.OrdinalIgnoreCase) == 0) {
// the final length is:
// fileName.Length + owner.MachineName.Length
// + 2 for the double slash
// + 7 for the \admin$
// - 12 for the %systemroot% we're removing.
StringBuilder result = new StringBuilder(fileName.Length + owner.MachineName.Length - 3);
result.Append(@"\\");
result.Append(owner.MachineName);
result.Append(@"\admin$");
result.Append(fileName, 12, fileName.Length - 12);
return result.ToString();
}
else if (fileName[1] == ':') {
StringBuilder result = new StringBuilder(fileName.Length + owner.MachineName.Length + 3);
result.Append(@"\\");
result.Append(owner.MachineName);
result.Append(@"\");
result.Append(fileName[0]);
result.Append("$");
result.Append(fileName, 2, fileName.Length - 2);
return result.ToString();
}
else
return null;
}
else {
// no need to expand environment variables, since this is done automatically by RegistryKey.GetValue()
return fileName;
}
}
private short ShortFrom(byte[] buf, int offset) {
// assumes little Endian byte order.
return(short) ((0xFF00 & (buf[offset+1] << 8)) | (0xFF & buf[offset]));
}
///
///
///
/// Saves an entry as a stream of data.
///
///
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
int len = IntFrom(dataBuf, bufOffset + FieldOffsets.LENGTH);
byte[] buf = new byte[len];
Array.Copy(dataBuf, bufOffset, buf, 0, len);
info.AddValue("DataBuffer", buf, typeof(byte[]));
info.AddValue("LogName", owner.Log);
info.AddValue("MachineName", owner.MachineName);
}
///
/// Stores the offsets from the beginning of the record to fields within the record.
///
private static class FieldOffsets {
/** int */
internal const int LENGTH = 0;
/** int */
internal const int RESERVED = 4;
/** int */
internal const int RECORDNUMBER = 8;
/** int */
internal const int TIMEGENERATED = 12;
/** int */
internal const int TIMEWRITTEN = 16;
/** int */
internal const int EVENTID = 20;
/** short */
internal const int EVENTTYPE = 24;
/** short */
internal const int NUMSTRINGS = 26;
/** short */
internal const int EVENTCATEGORY = 28;
/** short */
internal const int RESERVEDFLAGS = 30;
/** int */
internal const int CLOSINGRECORDNUMBER = 32;
/** int */
internal const int STRINGOFFSET = 36;
/** int */
internal const int USERSIDLENGTH = 40;
/** int */
internal const int USERSIDOFFSET = 44;
/** int */
internal const int DATALENGTH = 48;
/** int */
internal const int DATAOFFSET = 52;
/** bytes */
internal const int RAWDATA = 56;
}
// times in the struct are # seconds from midnight 1/1/1970.
private static readonly DateTime beginningOfTime = new DateTime(1970, 1, 1, 0, 0, 0);
// offsets in the struct are specified from the beginning, but we have to reference
// them from the beginning of the array. This is the size of the members before that.
private const int OFFSETFIXUP = 4+4+4+4+4+4+2+2+2+2+4+4+4+4+4+4;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Diagnostics {
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.ComponentModel;
using System.Diagnostics;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System;
using System.Security;
using System.Security.Permissions;
using System.IO;
using System.Globalization;
using System.Runtime.Versioning;
///
///
///
/// encapsulates a single record in the NT event log.
///
///
[
ToolboxItem(false),
DesignTimeVisible(false),
Serializable,
]
public sealed class EventLogEntry : Component, ISerializable {
internal byte[] dataBuf;
internal int bufOffset;
private EventLog owner;
private string category;
private string message;
// make sure only others in this package can create us
internal EventLogEntry(byte[] buf, int offset, EventLog log) {
this.dataBuf = buf;
this.bufOffset = offset;
this.owner = log;
GC.SuppressFinalize(this);
}
///
///
///
private EventLogEntry(SerializationInfo info, StreamingContext context) {
dataBuf = (byte[])info.GetValue("DataBuffer", typeof(byte[]));
string logName = info.GetString("LogName");
string machineName = info.GetString("MachineName");
owner = new EventLog(logName, machineName, "");
GC.SuppressFinalize(this);
}
///
///
/// Gets the name of the computer on which this entry was generated.
///
///
///
[MonitoringDescription(SR.LogEntryMachineName)]
public string MachineName {
get {
// first skip over the source name
int pos = bufOffset + FieldOffsets.RAWDATA;
while (CharFrom(dataBuf, pos) != '\0')
pos += 2;
pos += 2;
char ch = CharFrom(dataBuf, pos);
StringBuilder buf = new StringBuilder();
while (ch != '\0') {
buf.Append(ch);
pos += 2;
ch = CharFrom(dataBuf, pos);
}
return buf.ToString();
}
}
///
///
/// Gets the binary data associated with the entry.
///
///
///
[
MonitoringDescription(SR.LogEntryData)
]
public byte[] Data {
get {
int dataLen = IntFrom(dataBuf, bufOffset + FieldOffsets.DATALENGTH);
byte[] data = new byte[dataLen];
Array.Copy(dataBuf, bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.DATAOFFSET),
data, 0, dataLen);
return data;
}
}
/*
///
///
/// Copies the binary data in the member into an
/// array.
///
///
///
///
/// An array of type .
///
///
///
public Byte[] getDataBytes() {
Byte[] data = new Byte[rec.dataLength];
for (int i = 0; i < data.Length; i++)
data[i] = new Byte(rec.buf[i]);
return data;
}
*/
///
///
/// Gets the index of this entry in the event
/// log.
///
///
[MonitoringDescription(SR.LogEntryIndex)]
public int Index {
get {
return IntFrom(dataBuf, bufOffset + FieldOffsets.RECORDNUMBER);
}
}
///
///
/// Gets the text associated with the for this entry.
///
///
///
[MonitoringDescription(SR.LogEntryCategory)]
public string Category {
get {
if (category == null) {
string dllName = GetMessageLibraryNames("CategoryMessageFile");
string cat = owner.FormatMessageWrapper(dllName, (uint) CategoryNumber, null);
if (cat == null)
category = "(" + CategoryNumber.ToString(CultureInfo.CurrentCulture) + ")";
else
category = cat;
}
return category;
}
}
///
///
/// Gets the application-specific category number for this entry
///
///
///
[
MonitoringDescription(SR.LogEntryCategoryNumber)
]
public short CategoryNumber {
get {
return ShortFrom(dataBuf, bufOffset + FieldOffsets.EVENTCATEGORY);
}
}
///
///
/// Gets the application-specific event indentifier of this entry.
///
///
///
[
MonitoringDescription(SR.LogEntryEventID),
Obsolete("This property has been deprecated. Please use System.Diagnostics.EventLogEntry.InstanceId instead. http://go.microsoft.com/fwlink/?linkid=14202")
]
public int EventID {
get {
// Apparently the top 2 bits of this number are not
// always 0. Strip them so the number looks nice to the user.
// The problem is, if the user were to want to call FormatMessage(),
// they'd need these two bits.
return IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID) & 0x3FFFFFFF;
}
}
///
///
///
/// Gets the type
/// of this entry.
///
///
///
[MonitoringDescription(SR.LogEntryEntryType)]
public EventLogEntryType EntryType {
get {
return(EventLogEntryType) ShortFrom(dataBuf, bufOffset + FieldOffsets.EVENTTYPE);
}
}
///
///
/// Gets the localized message corresponding to this event entry.
///
///
///
[
MonitoringDescription(SR.LogEntryMessage),
Editor("System.ComponentModel.Design.BinaryEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing)
]
public string Message {
get {
if (message == null) {
string dllNames = GetMessageLibraryNames("EventMessageFile");
int msgId = IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID);
string msg = owner.FormatMessageWrapper(dllNames, (uint)msgId, ReplacementStrings);
if (msg == null) {
StringBuilder msgBuf = new StringBuilder(SR.GetString(SR.MessageNotFormatted, msgId, Source));
string[] strings = ReplacementStrings;
for (int i = 0; i < strings.Length; i++) {
if (i != 0)
msgBuf.Append(", ");
msgBuf.Append("'");
msgBuf.Append(strings[i]);
msgBuf.Append("'");
}
msg = msgBuf.ToString();
}
else
msg = ReplaceMessageParameters( msg, ReplacementStrings );
message = msg;
}
return message;
}
}
///
///
/// Gets the name of the application that generated this event.
///
///
[MonitoringDescription(SR.LogEntrySource)]
public string Source {
get {
StringBuilder buf = new StringBuilder();
int pos = bufOffset + FieldOffsets.RAWDATA;
char ch = CharFrom(dataBuf, pos);
while (ch != '\0') {
buf.Append(ch);
pos += 2;
ch = CharFrom(dataBuf, pos);
}
return buf.ToString();
}
}
///
///
/// Gets the replacement strings
/// associated with the entry.
///
///
///
[MonitoringDescription(SR.LogEntryReplacementStrings)]
public string[] ReplacementStrings {
get {
string[] strings = new string[ShortFrom(dataBuf, bufOffset + FieldOffsets.NUMSTRINGS)];
int i = 0;
int bufpos = bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.STRINGOFFSET);
StringBuilder buf = new StringBuilder();
while (i < strings.Length) {
char ch = CharFrom(dataBuf, bufpos);
if (ch != '\0')
buf.Append(ch);
else {
strings[i] = buf.ToString();
i++;
buf = new StringBuilder();
}
bufpos += 2;
}
return strings;
}
}
[
MonitoringDescription(SR.LogEntryResourceId),
ComVisible(false)
]
public Int64 InstanceId {
get {
return (UInt32)IntFrom(dataBuf, bufOffset + FieldOffsets.EVENTID);
}
}
#if false
internal string StringsBuffer {
get {
StringBuilder buf = new StringBuilder();
int bufpos = bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.STRINGOFFSET);
int i = 0;
int numStrings = ShortFrom(dataBuf, bufOffset + FieldOffsets.NUMSTRINGS);
while (i < numStrings) {
char ch = CharFrom(dataBuf, bufpos);
buf.Append(ch);
bufpos += 2;
if (ch == '\0')
i++;
}
return buf.ToString();
}
}
#endif
///
///
/// Gets the time at which this event was generated, in local time.
///
///
///
[MonitoringDescription(SR.LogEntryTimeGenerated)]
public DateTime TimeGenerated {
get {
return beginningOfTime.AddSeconds(IntFrom(dataBuf, bufOffset + FieldOffsets.TIMEGENERATED)).ToLocalTime();
}
}
///
///
/// Gets
/// the time at which this event was written to the log, in local time.
///
///
///
[MonitoringDescription(SR.LogEntryTimeWritten)]
public DateTime TimeWritten {
get {
return beginningOfTime.AddSeconds(IntFrom(dataBuf, bufOffset + FieldOffsets.TIMEWRITTEN)).ToLocalTime();
}
}
///
///
/// Gets the name
/// of the user responsible for this event.
///
///
[MonitoringDescription(SR.LogEntryUserName)]
public string UserName {
get {
int sidLen = IntFrom(dataBuf, bufOffset + FieldOffsets.USERSIDLENGTH);
if (sidLen == 0)
return null;
byte[] sid = new byte[sidLen];
Array.Copy(dataBuf, bufOffset + IntFrom(dataBuf, bufOffset + FieldOffsets.USERSIDOFFSET),
sid, 0, sid.Length);
int[] nameUse = new int[1];
char[] name = new char[1024];
char[] refDomName = new char[1024];
int[] nameLen = new int[] {1024};
int[] refDomNameLen = new int[] {1024};
bool success = UnsafeNativeMethods.LookupAccountSid(MachineName, sid, name, nameLen, refDomName, refDomNameLen, nameUse);
if (!success) {
return "";
// NOTE, [....]: it would be nice to return error info, but the only right way to do that
// is to throw an exception. People don't want exceptions thrown in the property though.
#if false
if (Marshal.GetLastWin32Error() == ERROR_NONE_MAPPED)
// There are some SIDs (evidently rare) that are legitimate SIDs but don't
// have a mapping to a name.
return "";
else
throw new InvalidOperationException(SR.GetString(SR.NoAccountInfo), SharedUtils.CreateSafeWin32Exception());
#endif
}
StringBuilder username = new StringBuilder();
username.Append(refDomName, 0, refDomNameLen[0]);
username.Append("\\");
username.Append(name, 0, nameLen[0]);
return username.ToString();
}
}
private char CharFrom(byte[] buf, int offset) {
return(char) ShortFrom(buf, offset);
}
///
///
/// Performs a comparison between two event log entries.
///
///
///
public bool Equals(EventLogEntry otherEntry) {
if (otherEntry == null)
return false;
int ourLen = IntFrom(dataBuf, bufOffset + FieldOffsets.LENGTH);
int theirLen = IntFrom(otherEntry.dataBuf, otherEntry.bufOffset + FieldOffsets.LENGTH);
if (ourLen != theirLen) {
return false;
}
int min = bufOffset;
int max = bufOffset + ourLen;
int j = otherEntry.bufOffset;
for (int i = min; i < max; i++, j++)
if (dataBuf[i] != otherEntry.dataBuf[j]) {
return false;
}
return true;
}
private int IntFrom(byte[] buf, int offset) {
// assumes Little Endian byte order.
return(unchecked((int)0xFF000000) & (buf[offset+3] << 24)) | (0xFF0000 & (buf[offset+2] << 16)) |
(0xFF00 & (buf[offset+1] << 8)) | (0xFF & (buf[offset]));
}
// Replacing parameters '%n' in formated message using 'ParameterMessageFile' registry key.
internal string ReplaceMessageParameters( String msg, string[] insertionStrings ) {
int percentIdx = msg.IndexOf('%');
if ( percentIdx < 0 )
return msg; // no '%' at all
int startCopyIdx = 0; // start idx of last [....] msg chars to copy
int msgLength = msg.Length;
StringBuilder buf = new StringBuilder();
string paramDLLNames = GetMessageLibraryNames("ParameterMessageFile");
while ( percentIdx >= 0 ) {
string param = null;
// Convert numeric string after '%' to paramMsgID number.
int lasNumIdx = percentIdx + 1;
while ( lasNumIdx < msgLength && Char.IsDigit(msg, lasNumIdx) )
lasNumIdx++;
uint paramMsgID = 0;
// If we can't parse it, leave the paramMsgID as zero. We'll skip the replacement and just put
// the %xxxx into the final message.
if (lasNumIdx != percentIdx + 1 )
UInt32.TryParse( msg.Substring(percentIdx + 1, lasNumIdx - percentIdx - 1), out paramMsgID);
if ( paramMsgID != 0 )
param = owner.FormatMessageWrapper( paramDLLNames, paramMsgID, insertionStrings);
if ( param != null ) {
if ( percentIdx > startCopyIdx )
buf.Append(msg, startCopyIdx, percentIdx - startCopyIdx); // original chars from msg
buf.Append(param);
startCopyIdx = lasNumIdx;
}
percentIdx = msg.IndexOf('%', percentIdx + 1);
}
if ( msgLength - startCopyIdx > 0 )
buf.Append(msg, startCopyIdx, msgLength - startCopyIdx); // last span of original msg
return buf.ToString();
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
private static RegistryKey GetSourceRegKey(string logName, string source, string machineName) {
RegistryKey eventKey = null;
RegistryKey logKey = null;
try {
eventKey = EventLog.GetEventLogRegKey(machineName, false);
if (eventKey == null)
return null;
if (logName == null)
logKey = eventKey.OpenSubKey("Application", /*writable*/false);
else
logKey = eventKey.OpenSubKey(logName, /*writable*/false);
if (logKey == null)
return null;
return logKey.OpenSubKey(source, /*writable*/false);
}
finally {
if (eventKey != null) eventKey.Close();
if (logKey != null) logKey.Close();
}
}
// -----------------------------------------------------------------------------
// Returns DLL names list.
// libRegKey can be: "EventMessageFile", "CategoryMessageFile", "ParameterMessageFile"
private string GetMessageLibraryNames(string libRegKey ) {
// get the value stored in the registry
string fileName = null;
RegistryKey regKey = null;
try {
regKey = GetSourceRegKey(owner.Log, Source, owner.MachineName);
if (regKey != null) {
if (owner.MachineName == ".")
fileName = (string)regKey.GetValue(libRegKey);
else
fileName = (string)regKey.GetValue(libRegKey, null, RegistryValueOptions.DoNotExpandEnvironmentNames);
}
}
finally {
if (regKey != null)
regKey.Close();
}
if (fileName == null)
return null;
// convert any environment variables to their current values
// (the key might have something like %systemroot% in it.)
// if we're looking at a remote machine, just try to replace %systemroot% at the beginning
if (owner.MachineName != ".") {
if (fileName.EndsWith(EventLog.DllName, StringComparison.Ordinal)) {
// if it's our EventLogMessages.dll, just use the local copy
return EventLog.GetDllPath(".");
}
else if (String.Compare(fileName, 0, "%systemroot%", 0, 12, StringComparison.OrdinalIgnoreCase) == 0) {
// the final length is:
// fileName.Length + owner.MachineName.Length
// + 2 for the double slash
// + 7 for the \admin$
// - 12 for the %systemroot% we're removing.
StringBuilder result = new StringBuilder(fileName.Length + owner.MachineName.Length - 3);
result.Append(@"\\");
result.Append(owner.MachineName);
result.Append(@"\admin$");
result.Append(fileName, 12, fileName.Length - 12);
return result.ToString();
}
else if (fileName[1] == ':') {
StringBuilder result = new StringBuilder(fileName.Length + owner.MachineName.Length + 3);
result.Append(@"\\");
result.Append(owner.MachineName);
result.Append(@"\");
result.Append(fileName[0]);
result.Append("$");
result.Append(fileName, 2, fileName.Length - 2);
return result.ToString();
}
else
return null;
}
else {
// no need to expand environment variables, since this is done automatically by RegistryKey.GetValue()
return fileName;
}
}
private short ShortFrom(byte[] buf, int offset) {
// assumes little Endian byte order.
return(short) ((0xFF00 & (buf[offset+1] << 8)) | (0xFF & buf[offset]));
}
///
///
///
/// Saves an entry as a stream of data.
///
///
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
int len = IntFrom(dataBuf, bufOffset + FieldOffsets.LENGTH);
byte[] buf = new byte[len];
Array.Copy(dataBuf, bufOffset, buf, 0, len);
info.AddValue("DataBuffer", buf, typeof(byte[]));
info.AddValue("LogName", owner.Log);
info.AddValue("MachineName", owner.MachineName);
}
///
/// Stores the offsets from the beginning of the record to fields within the record.
///
private static class FieldOffsets {
/** int */
internal const int LENGTH = 0;
/** int */
internal const int RESERVED = 4;
/** int */
internal const int RECORDNUMBER = 8;
/** int */
internal const int TIMEGENERATED = 12;
/** int */
internal const int TIMEWRITTEN = 16;
/** int */
internal const int EVENTID = 20;
/** short */
internal const int EVENTTYPE = 24;
/** short */
internal const int NUMSTRINGS = 26;
/** short */
internal const int EVENTCATEGORY = 28;
/** short */
internal const int RESERVEDFLAGS = 30;
/** int */
internal const int CLOSINGRECORDNUMBER = 32;
/** int */
internal const int STRINGOFFSET = 36;
/** int */
internal const int USERSIDLENGTH = 40;
/** int */
internal const int USERSIDOFFSET = 44;
/** int */
internal const int DATALENGTH = 48;
/** int */
internal const int DATAOFFSET = 52;
/** bytes */
internal const int RAWDATA = 56;
}
// times in the struct are # seconds from midnight 1/1/1970.
private static readonly DateTime beginningOfTime = new DateTime(1970, 1, 1, 0, 0, 0);
// offsets in the struct are specified from the beginning, but we have to reference
// them from the beginning of the array. This is the size of the members before that.
private const int OFFSETFIXUP = 4+4+4+4+4+4+2+2+2+2+4+4+4+4+4+4;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CodeDelegateCreateExpression.cs
- StatusBarItemAutomationPeer.cs
- ListViewInsertionMark.cs
- ImageSourceValueSerializer.cs
- LinkedResource.cs
- BitSet.cs
- DesignerDataConnection.cs
- HttpBrowserCapabilitiesBase.cs
- Vector3DAnimationUsingKeyFrames.cs
- FileFormatException.cs
- OleAutBinder.cs
- AccessibleObject.cs
- OleDbCommandBuilder.cs
- TableFieldsEditor.cs
- COSERVERINFO.cs
- SelectedDatesCollection.cs
- UnmanagedBitmapWrapper.cs
- SynchronizationContext.cs
- DesignerAttribute.cs
- VersionPair.cs
- DnsElement.cs
- RestHandlerFactory.cs
- UnSafeCharBuffer.cs
- OdbcConnectionPoolProviderInfo.cs
- FactoryGenerator.cs
- GACIdentityPermission.cs
- AnnotationResourceCollection.cs
- ImageListStreamer.cs
- PropertyGridView.cs
- DataGridViewCheckBoxCell.cs
- TextContainerHelper.cs
- TextEffectCollection.cs
- LogSwitch.cs
- DataViewManagerListItemTypeDescriptor.cs
- DrawingVisualDrawingContext.cs
- TextServicesDisplayAttribute.cs
- RowCache.cs
- NumberEdit.cs
- PipeSecurity.cs
- ServiceDiscoveryBehavior.cs
- webclient.cs
- TypeDescriptionProvider.cs
- WindowHelperService.cs
- MatchAttribute.cs
- LoadWorkflowByInstanceKeyCommand.cs
- ClickablePoint.cs
- LayoutTableCell.cs
- NodeFunctions.cs
- SafeArrayTypeMismatchException.cs
- MediaSystem.cs
- ZipFileInfoCollection.cs
- OpCodes.cs
- CqlParserHelpers.cs
- Int32AnimationUsingKeyFrames.cs
- ListSourceHelper.cs
- ObjectDataSourceSelectingEventArgs.cs
- VolatileEnlistmentState.cs
- StringKeyFrameCollection.cs
- ProcessManager.cs
- SequenceFullException.cs
- RefreshEventArgs.cs
- Expressions.cs
- JumpList.cs
- ValidationManager.cs
- ContextMenuStrip.cs
- DbProviderFactory.cs
- LoadWorkflowByInstanceKeyCommand.cs
- TemplateKeyConverter.cs
- GC.cs
- MetadataCollection.cs
- FacetChecker.cs
- base64Transforms.cs
- ItemList.cs
- AsymmetricCryptoHandle.cs
- ValidationHelpers.cs
- XmlSchemaSet.cs
- MobileFormsAuthentication.cs
- CodeSnippetStatement.cs
- DecoderBestFitFallback.cs
- SourceSwitch.cs
- X500Name.cs
- IndentedWriter.cs
- WebEvents.cs
- _AutoWebProxyScriptWrapper.cs
- DrawingBrush.cs
- ScriptComponentDescriptor.cs
- DataPagerField.cs
- CachedResourceDictionaryExtension.cs
- CharacterBufferReference.cs
- _UncName.cs
- ComponentEvent.cs
- ObjectSet.cs
- StringComparer.cs
- AsyncResult.cs
- NodeFunctions.cs
- selecteditemcollection.cs
- DiscriminatorMap.cs
- ExpressionBuilderCollection.cs
- PhonemeEventArgs.cs
- WebPartHelpVerb.cs