2 // System.Diagnostics.EventLogImpl.cs
5 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
6 // Atsushi Enomoto <atsushi@ximian.com>
7 // Gert Driesen (drieseng@users.sourceforge.net)
9 // (C) 2003 Andreas Nahr
10 // (C) 2006 Novell, Inc.
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.ComponentModel;
35 using System.ComponentModel.Design;
36 using System.Diagnostics;
37 using System.Globalization;
39 using Microsoft.Win32;
41 namespace System.Diagnostics
43 internal abstract class EventLogImpl
45 readonly EventLog _coreEventLog;
47 protected EventLogImpl (EventLog coreEventLog)
49 _coreEventLog = coreEventLog;
52 protected EventLog CoreEventLog {
53 get { return _coreEventLog; }
56 public int EntryCount {
58 if (_coreEventLog.Log == null || _coreEventLog.Log.Length == 0) {
59 throw new ArgumentException ("Log property is not set.");
62 if (!EventLog.Exists (_coreEventLog.Log, _coreEventLog.MachineName)) {
63 throw new InvalidOperationException (string.Format (
64 CultureInfo.InvariantCulture, "The event log '{0}' on "
65 + " computer '{1}' does not exist.", _coreEventLog.Log,
66 _coreEventLog.MachineName));
69 return GetEntryCount ();
73 public EventLogEntry this[int index] {
75 if (_coreEventLog.Log == null || _coreEventLog.Log.Length == 0) {
76 throw new ArgumentException ("Log property is not set.");
79 if (!EventLog.Exists (_coreEventLog.Log, _coreEventLog.MachineName)) {
80 throw new InvalidOperationException (string.Format (
81 CultureInfo.InvariantCulture, "The event log '{0}' on "
82 + " computer '{1}' does not exist.", _coreEventLog.Log,
83 _coreEventLog.MachineName));
86 if (index < 0 || index >= EntryCount)
87 throw new ArgumentException ("Index out of range");
89 return GetEntry (index);
93 public string LogDisplayName {
95 // to-do perform valid character checks
96 if (_coreEventLog.Log != null && _coreEventLog.Log.Length == 0) {
97 throw new InvalidOperationException ("Event log names must"
98 + " consist of printable characters and cannot contain"
99 + " \\, *, ?, or spaces.");
101 if (_coreEventLog.Log != null) {
102 if (_coreEventLog.Log.Length == 0)
105 if (!EventLog.Exists (_coreEventLog.Log, _coreEventLog.MachineName)) {
106 throw new InvalidOperationException (string.Format (
107 CultureInfo.InvariantCulture, "Cannot find Log {0}"
108 + " on computer {1}.", _coreEventLog.Log,
109 _coreEventLog.MachineName));
113 return GetLogDisplayName ();
117 public EventLogEntry [] GetEntries ()
119 string logName = CoreEventLog.Log;
120 if (logName == null || logName.Length == 0)
121 throw new ArgumentException ("Log property value has not been specified.");
123 if (!EventLog.Exists (logName))
124 throw new InvalidOperationException (string.Format (
125 CultureInfo.InvariantCulture, "The event log '{0}' on "
126 + " computer '{1}' does not exist.", logName,
127 _coreEventLog.MachineName));
129 int entryCount = GetEntryCount ();
130 EventLogEntry [] entries = new EventLogEntry [entryCount];
131 for (int i = 0; i < entryCount; i++) {
132 entries [i] = GetEntry (i);
137 public abstract void DisableNotification ();
139 public abstract void EnableNotification ();
141 public abstract void BeginInit ();
143 public abstract void Clear ();
145 public abstract void Close ();
147 public abstract void CreateEventSource (EventSourceCreationData sourceData);
149 public abstract void Delete (string logName, string machineName);
151 public abstract void DeleteEventSource (string source, string machineName);
153 public abstract void Dispose (bool disposing);
155 public abstract void EndInit ();
157 public abstract bool Exists (string logName, string machineName);
159 protected abstract int GetEntryCount ();
161 protected abstract EventLogEntry GetEntry (int index);
163 public EventLog [] GetEventLogs (string machineName)
165 string [] logNames = GetLogNames (machineName);
166 EventLog [] eventLogs = new EventLog [logNames.Length];
167 for (int i = 0; i < logNames.Length; i++) {
168 EventLog eventLog = new EventLog (logNames [i], machineName);
169 eventLogs [i] = eventLog;
174 protected abstract string GetLogDisplayName ();
176 public abstract string LogNameFromSourceName (string source, string machineName);
178 public abstract bool SourceExists (string source, string machineName);
180 public abstract void WriteEntry (string [] replacementStrings, EventLogEntryType type, uint instanceID, short category, byte[] rawData);
182 protected abstract string FormatMessage (string source, uint messageID, string [] replacementStrings);
184 protected abstract string [] GetLogNames (string machineName);
186 protected void ValidateCustomerLogName (string logName, string machineName)
188 if (logName.Length >= 8) {
189 string significantName = logName.Substring (0, 8);
190 if (string.Compare (significantName, "AppEvent", true) == 0 || string.Compare (significantName, "SysEvent", true) == 0 || string.Compare (significantName, "SecEvent", true) == 0)
191 throw new ArgumentException (string.Format (
192 CultureInfo.InvariantCulture, "The log name: '{0}' is"
193 + " invalid for customer log creation.", logName));
195 // the first 8 characters of the log name are used as filename
196 // for .evt file and as such no two logs with 8 characters or
197 // more should have the same first 8 characters (or the .evt
198 // would be overwritten)
200 // this check is not strictly necessary on unix
201 string [] logs = GetLogNames (machineName);
202 for (int i = 0; i < logs.Length; i++) {
203 string log = logs [i];
204 if (log.Length >= 8 && string.Compare (log, 0, significantName, 0, 8, true) == 0)
205 throw new ArgumentException (string.Format (
206 CultureInfo.InvariantCulture, "Only the first eight"
207 + " characters of a custom log name are significant,"
208 + " and there is already another log on the system"
209 + " using the first eight characters of the name given."
210 + " Name given: '{0}', name of existing log: '{1}'.",
215 // LAMESPEC: check if the log name matches an existing source
216 // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=186552
217 if (SourceExists (logName, machineName)) {
218 if (machineName == ".")
219 throw new ArgumentException (string.Format (
220 CultureInfo.InvariantCulture, "Log {0} has already been"
221 + " registered as a source on the local computer.",
224 throw new ArgumentException (string.Format (
225 CultureInfo.InvariantCulture, "Log {0} has already been"
226 + " registered as a source on the computer {1}.",
227 logName, machineName));
231 public abstract OverflowAction OverflowAction { get; }
233 public abstract int MinimumRetentionDays { get; }
235 public abstract long MaximumKilobytes { get; set; }
237 public abstract void ModifyOverflowPolicy (OverflowAction action, int retentionDays);
239 public abstract void RegisterDisplayName (string resourceFile, long resourceId);