BindingFlags.Public needed here as Exception.HResult is now public in .NET 4.5. This...
[mono.git] / mcs / class / System / System.Diagnostics / EventLogImpl.cs
1 //
2 // System.Diagnostics.EventLogImpl.cs
3 //
4 // Authors:
5 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
6 //   Atsushi Enomoto  <atsushi@ximian.com>
7 //   Gert Driesen (drieseng@users.sourceforge.net)
8 //
9 // (C) 2003 Andreas Nahr
10 // (C) 2006 Novell, Inc.
11 //
12 //
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:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
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.
31 //
32
33 using System;
34 using System.ComponentModel;
35 using System.ComponentModel.Design;
36 using System.Diagnostics;
37 using System.Globalization;
38
39 using Microsoft.Win32;
40
41 namespace System.Diagnostics
42 {
43         internal abstract class EventLogImpl
44         {
45                 readonly EventLog _coreEventLog;
46
47                 protected EventLogImpl (EventLog coreEventLog)
48                 {
49                         _coreEventLog = coreEventLog;
50                 }
51
52                 protected EventLog CoreEventLog {
53                         get { return _coreEventLog; }
54                 }
55
56                 public int EntryCount {
57                         get {
58                                 if (_coreEventLog.Log == null || _coreEventLog.Log.Length == 0) {
59                                         throw new ArgumentException ("Log property is not set.");
60                                 }
61
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));
67                                 }
68
69                                 return GetEntryCount ();
70                         }
71                 }
72
73                 public EventLogEntry this[int index] {
74                         get {
75                                 if (_coreEventLog.Log == null || _coreEventLog.Log.Length == 0) {
76                                         throw new ArgumentException ("Log property is not set.");
77                                 }
78
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));
84                                 }
85
86                                 if (index < 0 || index >= EntryCount)
87                                         throw new ArgumentException ("Index out of range");
88
89                                 return GetEntry (index);
90                         }
91                 }
92
93                 public string LogDisplayName {
94                         get {
95 #if NET_2_0
96                                 // to-do perform valid character checks
97                                 if (_coreEventLog.Log != null && _coreEventLog.Log.Length == 0) {
98                                         throw new InvalidOperationException ("Event log names must"
99                                                 + " consist of printable characters and cannot contain"
100                                                 + " \\, *, ?, or spaces.");
101                                 }
102 #endif
103                                 if (_coreEventLog.Log != null) {
104                                         if (_coreEventLog.Log.Length == 0)
105                                                 return string.Empty;
106
107                                         if (!EventLog.Exists (_coreEventLog.Log, _coreEventLog.MachineName)) {
108                                                 throw new InvalidOperationException (string.Format (
109                                                         CultureInfo.InvariantCulture, "Cannot find Log {0}"
110                                                         + " on computer {1}.", _coreEventLog.Log,
111                                                         _coreEventLog.MachineName));
112                                         }
113                                 }
114
115                                 return GetLogDisplayName ();
116                         }
117                 }
118
119                 public EventLogEntry [] GetEntries ()
120                 {
121                         string logName = CoreEventLog.Log;
122                         if (logName == null || logName.Length == 0)
123                                 throw new ArgumentException ("Log property value has not been specified.");
124
125                         if (!EventLog.Exists (logName))
126                                 throw new InvalidOperationException (string.Format (
127                                         CultureInfo.InvariantCulture, "The event log '{0}' on "
128                                         + " computer '{1}' does not exist.", logName,
129                                         _coreEventLog.MachineName));
130
131                         int entryCount = GetEntryCount ();
132                         EventLogEntry [] entries = new EventLogEntry [entryCount];
133                         for (int i = 0; i < entryCount; i++) {
134                                 entries [i] = GetEntry (i);
135                         }
136                         return entries;
137                 }
138
139                 public abstract void DisableNotification ();
140
141                 public abstract void EnableNotification ();
142
143                 public abstract void BeginInit ();
144
145                 public abstract void Clear ();
146
147                 public abstract void Close ();
148
149                 public abstract void CreateEventSource (EventSourceCreationData sourceData);
150
151                 public abstract void Delete (string logName, string machineName);
152
153                 public abstract void DeleteEventSource (string source, string machineName);
154
155                 public abstract void Dispose (bool disposing);
156
157                 public abstract void EndInit ();
158
159                 public abstract bool Exists (string logName, string machineName);
160
161                 protected abstract int GetEntryCount ();
162
163                 protected abstract EventLogEntry GetEntry (int index);
164
165                 public EventLog [] GetEventLogs (string machineName)
166                 {
167                         string [] logNames = GetLogNames (machineName);
168                         EventLog [] eventLogs = new EventLog [logNames.Length];
169                         for (int i = 0; i < logNames.Length; i++) {
170                                 EventLog eventLog = new EventLog (logNames [i], machineName);
171                                 eventLogs [i] = eventLog;
172                         }
173                         return eventLogs;
174                 }
175
176                 protected abstract string GetLogDisplayName ();
177
178                 public abstract string LogNameFromSourceName (string source, string machineName);
179
180                 public abstract bool SourceExists (string source, string machineName);
181
182                 public abstract void WriteEntry (string [] replacementStrings, EventLogEntryType type, uint instanceID, short category, byte[] rawData);
183
184                 protected abstract string FormatMessage (string source, uint messageID, string [] replacementStrings);
185
186                 protected abstract string [] GetLogNames (string machineName);
187
188                 protected void ValidateCustomerLogName (string logName, string machineName)
189                 {
190                         if (logName.Length >= 8) {
191                                 string significantName = logName.Substring (0, 8);
192                                 if (string.Compare (significantName, "AppEvent", true) == 0 || string.Compare (significantName, "SysEvent", true) == 0 || string.Compare (significantName, "SecEvent", true) == 0)
193                                         throw new ArgumentException (string.Format (
194                                                 CultureInfo.InvariantCulture, "The log name: '{0}' is"
195                                                 + " invalid for customer log creation.", logName));
196
197                                 // the first 8 characters of the log name are used as  filename
198                                 // for .evt file and as such no two logs with 8 characters or 
199                                 // more should have the same first 8 characters (or the .evt
200                                 // would be overwritten)
201                                 //
202                                 // this check is not strictly necessary on unix
203                                 string [] logs = GetLogNames (machineName);
204                                 for (int i = 0; i < logs.Length; i++) {
205                                         string log = logs [i];
206                                         if (log.Length >= 8 && string.Compare (log, 0, significantName, 0, 8, true) == 0)
207                                                 throw new ArgumentException (string.Format (
208                                                         CultureInfo.InvariantCulture, "Only the first eight"
209                                                         + " characters of a custom log name are significant,"
210                                                         + " and there is already another log on the system"
211                                                         + " using the first eight characters of the name given."
212                                                         + " Name given: '{0}', name of existing log: '{1}'.",
213                                                         logName, log));
214                                 }
215                         }
216
217                         // LAMESPEC: check if the log name matches an existing source
218                         // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=186552
219                         if (SourceExists (logName, machineName)) {
220                                 if (machineName == ".")
221                                         throw new ArgumentException (string.Format (
222                                                 CultureInfo.InvariantCulture, "Log {0} has already been"
223                                                 + " registered as a source on the local computer.", 
224                                                 logName));
225                                 else
226                                         throw new ArgumentException (string.Format (
227                                                 CultureInfo.InvariantCulture, "Log {0} has already been"
228                                                 + " registered as a source on the computer {1}.",
229                                                 logName, machineName));
230                         }
231                 }
232
233 #if NET_2_0
234                 public abstract OverflowAction OverflowAction { get; }
235
236                 public abstract int MinimumRetentionDays { get; }
237
238                 public abstract long MaximumKilobytes { get; set; }
239
240                 public abstract void ModifyOverflowPolicy (OverflowAction action, int retentionDays);
241
242                 public abstract void RegisterDisplayName (string resourceFile, long resourceId);
243 #endif
244         }
245 }