|
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: EventLogSession
**
** Purpose:
** Defines a session for Event Log operations. The session can
** be configured for a remote machine and can use specfic
** user credentials.
============================================================*/
using System;
using System.Security;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.Win32;
using System.Globalization;
namespace System.Diagnostics.Eventing.Reader {
/// <summary>
/// Session Login Type
/// </summary>
public enum SessionAuthentication {
Default = 0,
Negotiate = 1,
Kerberos = 2,
Ntlm = 3
}
/// <summary>
/// The type: log / external log file to query
/// </summary>
public enum PathType
{
LogName = 1,
FilePath = 2
}
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
public class EventLogSession : IDisposable {
//
//the two context handles for rendering (for EventLogRecord).
//the system and user context handles. They are both common for all the event instances and can be created only once.
//access to the data member references is safe, while
//invoking methods on it is marked SecurityCritical as appropriate.
//
internal EventLogHandle renderContextHandleSystem = EventLogHandle.Zero;
internal EventLogHandle renderContextHandleUser = EventLogHandle.Zero;
//the dummy sync object for the two contextes.
private object syncObject = null;
private string server;
private string user;
private string domain;
private SessionAuthentication logOnType;
//we do not maintain the password here.
//
//access to the data member references is safe, while
//invoking methods on it is marked SecurityCritical as appropriate.
//
private EventLogHandle handle = EventLogHandle.Zero;
//setup the System Context, once for all the EventRecords.
[System.Security.SecuritySafeCritical]
internal void SetupSystemContext() {
EventLogPermissionHolder.GetEventLogPermission().Demand();
if (!this.renderContextHandleSystem.IsInvalid)
return;
lock (this.syncObject) {
if (this.renderContextHandleSystem.IsInvalid) {
//create the SYSTEM render context
//call the EvtCreateRenderContext to get the renderContextHandleSystem, so that we can get the system/values/user properties.
this.renderContextHandleSystem = NativeWrapper.EvtCreateRenderContext(0, null, UnsafeNativeMethods.EvtRenderContextFlags.EvtRenderContextSystem);
}
}
}
[System.Security.SecuritySafeCritical]
internal void SetupUserContext() {
EventLogPermissionHolder.GetEventLogPermission().Demand();
lock (this.syncObject) {
if (this.renderContextHandleUser.IsInvalid) {
//create the USER render context
this.renderContextHandleUser = NativeWrapper.EvtCreateRenderContext(0, null, UnsafeNativeMethods.EvtRenderContextFlags.EvtRenderContextUser);
}
}
}
// marked as SecurityCritical because allocates SafeHandle.
// marked as TreatAsSafe because performs Demand().
[System.Security.SecurityCritical]
public EventLogSession() {
EventLogPermissionHolder.GetEventLogPermission().Demand();
//handle = EventLogHandle.Zero;
syncObject = new object();
}
public EventLogSession(string server)
:
this(server, null, null, (SecureString)null, SessionAuthentication.Default) {
}
// marked as TreatAsSafe because performs Demand().
[System.Security.SecurityCritical]
public EventLogSession(string server, string domain, string user, SecureString password, SessionAuthentication logOnType) {
EventLogPermissionHolder.GetEventLogPermission().Demand();
if (server == null)
server = "localhost";
syncObject = new object();
this.server = server;
this.domain = domain;
this.user = user;
this.logOnType = logOnType;
UnsafeNativeMethods.EvtRpcLogin erLogin = new UnsafeNativeMethods.EvtRpcLogin();
erLogin.Server = this.server;
erLogin.User = this.user;
erLogin.Domain = this.domain;
erLogin.Flags = (int)this.logOnType;
erLogin.Password = CoTaskMemUnicodeSafeHandle.Zero;
try {
if (password != null)
erLogin.Password.SetMemory(Marshal.SecureStringToCoTaskMemUnicode(password));
//open a session using the erLogin structure.
handle = NativeWrapper.EvtOpenSession(UnsafeNativeMethods.EvtLoginClass.EvtRpcLogin, ref erLogin, 0, 0);
}
finally {
erLogin.Password.Close();
}
}
internal EventLogHandle Handle {
get {
return handle;
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
[System.Security.SecuritySafeCritical]
protected virtual void Dispose(bool disposing) {
if (disposing) {
if ( this == globalSession )
throw new InvalidOperationException();
EventLogPermissionHolder.GetEventLogPermission().Demand();
}
if (this.renderContextHandleSystem != null &&
!this.renderContextHandleSystem.IsInvalid)
this.renderContextHandleSystem.Dispose();
if (this.renderContextHandleUser != null &&
!this.renderContextHandleUser.IsInvalid)
this.renderContextHandleUser.Dispose();
if (handle != null && !handle.IsInvalid)
handle.Dispose();
}
public void CancelCurrentOperations() {
NativeWrapper.EvtCancel(handle);
}
static EventLogSession globalSession = new EventLogSession();
public static EventLogSession GlobalSession {
get { return globalSession; }
}
[System.Security.SecurityCritical]
public IEnumerable<string> GetProviderNames()
{
EventLogPermissionHolder.GetEventLogPermission().Demand();
List<string> namesList = new List<string>(100);
using (EventLogHandle ProviderEnum = NativeWrapper.EvtOpenProviderEnum(this.Handle, 0))
{
bool finish = false;
do
{
string s = NativeWrapper.EvtNextPublisherId(ProviderEnum, ref finish);
if (finish == false) namesList.Add(s);
}
while (finish == false);
return namesList;
}
}
[System.Security.SecurityCritical]
public IEnumerable<string> GetLogNames()
{
EventLogPermissionHolder.GetEventLogPermission().Demand();
List<string> namesList = new List<string>(100);
using (EventLogHandle channelEnum = NativeWrapper.EvtOpenChannelEnum(this.Handle, 0))
{
bool finish = false;
do
{
string s = NativeWrapper.EvtNextChannelPath(channelEnum, ref finish);
if (finish == false) namesList.Add(s);
}
while (finish == false);
return namesList;
}
}
public EventLogInformation GetLogInformation(string logName, PathType pathType) {
if (logName == null)
throw new ArgumentNullException("logName");
return new EventLogInformation(this, logName, pathType);
}
public void ExportLog(string path, PathType pathType, string query, string targetFilePath) {
this.ExportLog(path, pathType, query, targetFilePath, false);
}
public void ExportLog(string path, PathType pathType, string query, string targetFilePath, bool tolerateQueryErrors)
{
if (path == null)
throw new ArgumentNullException("path");
if (targetFilePath == null)
throw new ArgumentNullException("targetFilePath");
UnsafeNativeMethods.EvtExportLogFlags flag;
switch (pathType)
{
case PathType.LogName:
flag = UnsafeNativeMethods.EvtExportLogFlags.EvtExportLogChannelPath;
break;
case PathType.FilePath:
flag = UnsafeNativeMethods.EvtExportLogFlags.EvtExportLogFilePath;
break;
default:
throw new ArgumentOutOfRangeException("pathType");
}
if (tolerateQueryErrors == false)
NativeWrapper.EvtExportLog(this.Handle, path, query, targetFilePath, (int)flag);
else
NativeWrapper.EvtExportLog(this.Handle, path, query, targetFilePath, (int)flag | (int)UnsafeNativeMethods.EvtExportLogFlags.EvtExportLogTolerateQueryErrors);
}
public void ExportLogAndMessages(string path, PathType pathType, string query, string targetFilePath)
{
this.ExportLogAndMessages(path, pathType, query, targetFilePath, false, CultureInfo.CurrentCulture );
}
public void ExportLogAndMessages(string path, PathType pathType, string query, string targetFilePath, bool tolerateQueryErrors, CultureInfo targetCultureInfo ) {
if (targetCultureInfo == null)
targetCultureInfo = CultureInfo.CurrentCulture;
ExportLog(path, pathType, query, targetFilePath, tolerateQueryErrors);
NativeWrapper.EvtArchiveExportedLog(this.Handle, targetFilePath, targetCultureInfo.LCID, 0);
}
public void ClearLog(string logName)
{
this.ClearLog(logName, null);
}
public void ClearLog(string logName, string backupPath)
{
if (logName == null)
throw new ArgumentNullException("logName");
NativeWrapper.EvtClearLog(this.Handle, logName, backupPath, 0);
}
}
}
|