Vanara/PInvoke/Security/AdvApi32/WinBase.EventLog.cs

692 lines
37 KiB
C#

using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public static partial class AdvApi32
{
/// <summary/>
public const uint ELF_LOG_SIGNATURE = 0x654c664c;
/// <summary>Saves the specified event log to a backup file. The function does not clear the event log.</summary>
/// <param name="hEventLog">A handle to the open event log. The OpenEventLog function returns this handle.</param>
/// <param name="lpBackupFileName">The absolute or relative path of the backup file.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// The <c>BackupEventLog</c> function fails with the ERROR_PRIVILEGE_NOT_HELD error if the user does not have the SE_BACKUP_NAME privilege.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-backupeventloga BOOL BackupEventLogA( HANDLE hEventLog,
// LPCSTR lpBackupFileName );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winbase.h", MSDNShortId = "5cfd5bad-4401-4abd-9e81-5f139e4ecf73")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BackupEventLog(HEVENTLOG hEventLog, string lpBackupFileName);
/// <summary>Clears the specified event log, and optionally saves the current copy of the log to a backup file.</summary>
/// <param name="hEventLog">A handle to the event log to be cleared. The OpenEventLog function returns this handle.</param>
/// <param name="lpBackupFileName">
/// <para>The absolute or relative path of the backup file. If this file already exists, the function fails.</para>
/// <para>If the lpBackupFileName parameter is <c>NULL</c>, the event log is not backed up.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>
/// If the function fails, the return value is zero. To get extended error information, call GetLastError. The <c>ClearEventLog</c>
/// function can fail if the event log is empty or the backup file already exists.
/// </para>
/// </returns>
/// <remarks>After this function returns, any handles that reference the cleared event log cannot be used to read the log.</remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-cleareventloga BOOL ClearEventLogA( HANDLE hEventLog,
// LPCSTR lpBackupFileName );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winbase.h", MSDNShortId = "b66896f6-baee-43c4-9d9b-5663c164d092")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ClearEventLog(HEVENTLOG hEventLog, [Optional] string lpBackupFileName);
/// <summary>Closes the specified event log.</summary>
/// <param name="hEventLog">
/// A handle to the event log to be closed. The OpenEventLog or OpenBackupEventLog function returns this handle.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-closeeventlog BOOL CloseEventLog( HANDLE hEventLog );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbase.h", MSDNShortId = "cb98a0cf-8ee9-4d78-8508-efae1d43a91d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseEventLog(HEVENTLOG hEventLog);
/// <summary>Closes the specified event log.</summary>
/// <param name="hEventLog">A handle to the event log. The RegisterEventSource function returns this handle.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-deregistereventsource BOOL DeregisterEventSource( HANDLE
// hEventLog );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbase.h", MSDNShortId = "f5d1f4b0-5320-4aec-a129-cafff6f1fed1")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeregisterEventSource(HEVENTLOG hEventLog);
/// <summary>Retrieves information about the specified event log.</summary>
/// <param name="hEventLog">A handle to the event log. The OpenEventLog or RegisterEventSource function returns this handle.</param>
/// <param name="dwInfoLevel">
/// The level of event log information to return.
/// <para>This parameter can be the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>EVENTLOG_FULL_INFO</term>
/// <term>Indicate whether the specified log is full. The lpBuffer parameter will contain an EVENTLOG_FULL_INFORMATION structure.</term>
/// </item>
/// </list>
/// </param>
/// <param name="lpBuffer">
/// An application-allocated buffer that receives the event log information. The format of this data depends on the value of the
/// dwInfoLevel parameter.
/// </param>
/// <param name="cbBufSize">The size of the lpBuffer buffer, in bytes.</param>
/// <param name="pcbBytesNeeded">
/// The function sets this parameter to the required buffer size for the requested information, regardless of whether the function
/// succeeds. Use this value if the function fails with <c>ERROR_INSUFFICIENT_BUFFER</c> to allocate a buffer of the correct size.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-geteventloginformation BOOL GetEventLogInformation( HANDLE
// hEventLog, DWORD dwInfoLevel, LPVOID lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbase.h", MSDNShortId = "627e0af2-3ce6-47fe-89c6-d7c0483cb94b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetEventLogInformation(HEVENTLOG hEventLog, uint dwInfoLevel, IntPtr lpBuffer, uint cbBufSize, out uint pcbBytesNeeded);
/// <summary>Retrieves the number of records in the specified event log.</summary>
/// <param name="hEventLog">A handle to the open event log. The OpenEventLog or OpenBackupEventLog function returns this handle.</param>
/// <param name="NumberOfRecords">A pointer to a variable that receives the number of records in the specified event log.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// The oldest record in an event log is not necessarily record number 1. To determine the oldest record number in an event log, use
/// the GetOldestEventLogRecord function.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-getnumberofeventlogrecords BOOL
// GetNumberOfEventLogRecords( HANDLE hEventLog, PDWORD NumberOfRecords );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbase.h", MSDNShortId = "80cc8735-26a2-4ad3-a111-28f2c0c52e98")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetNumberOfEventLogRecords(HEVENTLOG hEventLog, out uint NumberOfRecords);
/// <summary>Retrieves the absolute record number of the oldest record in the specified event log.</summary>
/// <param name="hEventLog">A handle to the open event log. The OpenEventLog or OpenBackupEventLog function returns this handle.</param>
/// <param name="OldestRecord">
/// A pointer to a variable that receives the absolute record number of the oldest record in the specified event log.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>The oldest record in an event log is not necessarily record number 1. For more information, see Event Log Records.</para>
/// <para>Examples</para>
/// <para>For an example, see Querying for Event Information.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-getoldesteventlogrecord BOOL GetOldestEventLogRecord(
// HANDLE hEventLog, PDWORD OldestRecord );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbase.h", MSDNShortId = "2f64f82b-a5f5-4701-844b-5979a0124414")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetOldestEventLogRecord(HEVENTLOG hEventLog, out uint OldestRecord);
/// <summary>
/// Enables an application to receive notification when an event is written to the specified event log. When the event is written to
/// the log, the specified event object is set to the signaled state.
/// </summary>
/// <param name="hEventLog">A handle to an event log. The OpenEventLog function returns this handle.</param>
/// <param name="hEvent">
/// A handle to a manual-reset or auto-reset event object. Use the CreateEvent function to create the event object.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// The <c>NotifyChangeEventLog</c> function does not work with remote handles. If the hEventLog parameter is the handle to an event
/// log on a remote computer, <c>NotifyChangeEventLog</c> returns zero, and GetLastError returns <c>ERROR_INVALID_HANDLE</c>.
/// </para>
/// <para>
/// If the thread is not waiting on the event when the system calls PulseEvent, the thread will not receive the notification.
/// Therefore, you should create a separate thread to wait for notifications.
/// </para>
/// <para>
/// The system will continue to notify you of changes until you close the handle to the event log. To close the event log, use the
/// CloseEventLog or DeregisterEventSource function.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Receiving Event Notification.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-notifychangeeventlog BOOL NotifyChangeEventLog( HANDLE
// hEventLog, HANDLE hEvent );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winbase.h", MSDNShortId = "12b9a7bf-2aad-48b7-8cfd-a72b353ba2b2")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool NotifyChangeEventLog(HEVENTLOG hEventLog, Kernel32.SafeEventHandle hEvent);
/// <summary>Opens a handle to a backup event log created by the BackupEventLog function.</summary>
/// <param name="lpUNCServerName">
/// The Universal Naming Convention (UNC) name of the remote server on which this operation is to be performed. If this parameter is
/// <c>NULL</c>, the local computer is used.
/// </param>
/// <param name="lpFileName">The full path of the backup file.</param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the backup event log.</para>
/// <para>If the function fails, the return value is <c>NULL</c>. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>If the backup filename specifies a remote server, the lpUNCServerName parameter must be <c>NULL</c>.</para>
/// <para>
/// When this function is used on Windows Vista and later computers, only backup event logs that were saved with the
/// <c>BackupEventLog</c> function on Windows Vista and later computers can be opened.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-openbackupeventloga HANDLE OpenBackupEventLogA( LPCSTR
// lpUNCServerName, LPCSTR lpFileName );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winbase.h", MSDNShortId = "cfef0912-9d35-44aa-a1d3-f9bb37213ce0")]
public static extern SafeHEVENTLOG OpenBackupEventLog([Optional] string lpUNCServerName, string lpFileName);
/// <summary>Opens a handle to the specified event log.</summary>
/// <param name="lpUNCServerName">
/// The Universal Naming Convention (UNC) name of the remote server on which the event log is to be opened. If this parameter is
/// <c>NULL</c>, the local computer is used.
/// </param>
/// <param name="lpSourceName">
/// <para>The name of the log.</para>
/// <para>
/// If you specify a custom log and it cannot be found, the event logging service opens the <c>Application</c> log; however, there
/// will be no associated message or category string file.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is the handle to an event log.</para>
/// <para>If the function fails, the return value is <c>NULL</c>. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>To close the handle to the event log, use the CloseEventLog function.</para>
/// <para>Examples</para>
/// <para>For an example, see Querying for Event Information.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-openeventloga HANDLE OpenEventLogA( LPCSTR
// lpUNCServerName, LPCSTR lpSourceName );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winbase.h", MSDNShortId = "6cd8797a-aeaf-4603-b43c-b1ff45b6200a")]
public static extern SafeHEVENTLOG OpenEventLog([Optional] string lpUNCServerName, string lpSourceName);
/// <summary>
/// Reads the specified number of entries from the specified event log. The function can be used to read log entries in chronological
/// or reverse chronological order.
/// </summary>
/// <param name="hEventLog">A handle to the event log to be read. The OpenEventLog function returns this handle.</param>
/// <param name="dwReadFlags">
/// <para>
/// Use the following flag values to indicate how to read the log file. This parameter must include one of the following values (the
/// flags are mutually exclusive).
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>EVENTLOG_SEEK_READ 0x0002</term>
/// <term>
/// Begin reading from the record specified in the dwRecordOffset parameter. This option may not work with large log files if the
/// function cannot determine the log file's size. For details, see Knowledge Base article, 177199.
/// </term>
/// </item>
/// <item>
/// <term>EVENTLOG_SEQUENTIAL_READ 0x0001</term>
/// <term>Read the records sequentially.</term>
/// </item>
/// </list>
/// <para>
/// You must specify one of the following flags to indicate the direction for successive read operations (the flags are mutually exclusive).
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>EVENTLOG_FORWARDS_READ 0x0004</term>
/// <term>The log is read in chronological order (oldest to newest).</term>
/// </item>
/// <item>
/// <term>EVENTLOG_BACKWARDS_READ 0x0008</term>
/// <term>The log is read in reverse chronological order (newest to oldest).</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwRecordOffset">
/// The record number of the log-entry at which the read operation should start. This parameter is ignored unless dwReadFlags
/// includes the <c>EVENTLOG_SEEK_READ</c> flag.
/// </param>
/// <param name="lpBuffer">
/// <para>
/// An application-allocated buffer that will receive one or more EVENTLOGRECORD structures. This parameter cannot be <c>NULL</c>,
/// even if the nNumberOfBytesToRead parameter is zero.
/// </para>
/// <para>The maximum size of this buffer is 0x7ffff bytes.</para>
/// </param>
/// <param name="nNumberOfBytesToRead">
/// The size of the lpBuffer buffer, in bytes. This function will read as many log entries as will fit in the buffer; the function
/// will not return partial entries.
/// </param>
/// <param name="pnBytesRead">A pointer to a variable that receives the number of bytes read by the function.</param>
/// <param name="pnMinNumberOfBytesNeeded">
/// A pointer to a variable that receives the required size of the lpBuffer buffer. This value is valid only this function returns
/// zero and GetLastError returns <c>ERROR_INSUFFICIENT_BUFFER</c>.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>When this function returns successfully, the read position in the event log is adjusted by the number of records read.</para>
/// <para>
/// <c>Note</c> The configured file name for this source may also be the configured file name for other sources (several sources can
/// exist as subkeys under a single log). Therefore, this function may return events that were logged by more than one source.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Querying for Event Information.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-readeventloga BOOL ReadEventLogA( HANDLE hEventLog, DWORD
// dwReadFlags, DWORD dwRecordOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, DWORD *pnBytesRead, DWORD
// *pnMinNumberOfBytesNeeded );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winbase.h", MSDNShortId = "10b37174-661a-4dc6-a7fe-752739494156")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadEventLog(HEVENTLOG hEventLog, EVENTLOG_READ dwReadFlags, uint dwRecordOffset, IntPtr lpBuffer, uint nNumberOfBytesToRead, out uint pnBytesRead, out uint pnMinNumberOfBytesNeeded);
/// <summary>
/// Reads the specified number of entries from the specified event log. The function can be used to read log entries in chronological
/// or reverse chronological order.
/// </summary>
/// <param name="hEventLog">A handle to the event log to be read. The OpenEventLog function returns this handle.</param>
/// <param name="dwReadFlags">
/// <para>
/// Use the following flag values to indicate how to read the log file. This parameter must include one of the following values (the
/// flags are mutually exclusive).
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>EVENTLOG_SEEK_READ 0x0002</term>
/// <term>
/// Begin reading from the record specified in the dwRecordOffset parameter. This option may not work with large log files if the
/// function cannot determine the log file's size. For details, see Knowledge Base article, 177199.
/// </term>
/// </item>
/// <item>
/// <term>EVENTLOG_SEQUENTIAL_READ 0x0001</term>
/// <term>Read the records sequentially.</term>
/// </item>
/// </list>
/// <para>
/// You must specify one of the following flags to indicate the direction for successive read operations (the flags are mutually exclusive).
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>EVENTLOG_FORWARDS_READ 0x0004</term>
/// <term>The log is read in chronological order (oldest to newest).</term>
/// </item>
/// <item>
/// <term>EVENTLOG_BACKWARDS_READ 0x0008</term>
/// <term>The log is read in reverse chronological order (newest to oldest).</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwRecordOffset">
/// The record number of the log-entry at which the read operation should start. This parameter is ignored unless dwReadFlags
/// includes the <c>EVENTLOG_SEEK_READ</c> flag.
/// </param>
/// <param name="lpBuffer">
/// <para>
/// An application-allocated buffer that will receive one or more EVENTLOGRECORD structures. This parameter cannot be <c>NULL</c>,
/// even if the nNumberOfBytesToRead parameter is zero.
/// </para>
/// <para>The maximum size of this buffer is 0x7ffff bytes.</para>
/// </param>
/// <param name="nNumberOfBytesToRead">
/// The size of the lpBuffer buffer, in bytes. This function will read as many log entries as will fit in the buffer; the function
/// will not return partial entries.
/// </param>
/// <param name="pnBytesRead">A pointer to a variable that receives the number of bytes read by the function.</param>
/// <param name="pnMinNumberOfBytesNeeded">
/// A pointer to a variable that receives the required size of the lpBuffer buffer. This value is valid only this function returns
/// zero and GetLastError returns <c>ERROR_INSUFFICIENT_BUFFER</c>.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>When this function returns successfully, the read position in the event log is adjusted by the number of records read.</para>
/// <para>
/// <c>Note</c> The configured file name for this source may also be the configured file name for other sources (several sources can
/// exist as subkeys under a single log). Therefore, this function may return events that were logged by more than one source.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Querying for Event Information.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-readeventloga BOOL ReadEventLogA( HANDLE hEventLog, DWORD
// dwReadFlags, DWORD dwRecordOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, DWORD *pnBytesRead, DWORD
// *pnMinNumberOfBytesNeeded );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winbase.h", MSDNShortId = "10b37174-661a-4dc6-a7fe-752739494156")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadEventLog(HEVENTLOG hEventLog, EVENTLOG_READ dwReadFlags, uint dwRecordOffset, SafePEVENTLOGRECORD lpBuffer, uint nNumberOfBytesToRead, out uint pnBytesRead, out uint pnMinNumberOfBytesNeeded);
/// <summary>
/// <para>Retrieves a registered handle to the specified event log.</para>
/// </summary>
/// <param name="lpUNCServerName">
/// <para>
/// The Universal Naming Convention (UNC) name of the remote server on which this operation is to be performed. If this parameter is
/// <c>NULL</c>, the local computer is used.
/// </para>
/// </param>
/// <param name="lpSourceName">
/// <para>
/// The name of the event source whose handle is to be retrieved. The source name must be a subkey of a log under the <c>Eventlog</c>
/// registry key. Note that the <c>Security</c> log is for system use only.
/// </para>
/// <para>
/// <c>Note</c> This string must not contain characters prohibited in XML Attributes, with the exception of XML Escape sequences such
/// as <c>&amp;lt &amp;gl</c>.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the event log.</para>
/// <para>If the function fails, the return value is <c>NULL</c>. To get extended error information, call GetLastError.</para>
/// <para>The function returns <c>ERROR_ACCESS_DENIED</c> if lpSourceName specifies the <c>Security</c> event log.</para>
/// </returns>
/// <remarks>
/// <para>
/// If the source name cannot be found, the event logging service uses the <c>Application</c> log. Although events will be reported ,
/// the events will not include descriptions because there are no message and category message files for looking up descriptions
/// related to the event identifiers.
/// </para>
/// <para>To close the handle to the event log, use the DeregisterEventSource function.</para>
/// <para>Examples</para>
/// <para>For an example, see Reporting an Event.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-registereventsourcea HANDLE RegisterEventSourceA( LPCSTR
// lpUNCServerName, LPCSTR lpSourceName );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winbase.h", MSDNShortId = "53706f83-6bc9-45d6-981c-bd0680d7bc08")]
public static extern SafeHEVENTSOURCE RegisterEventSource([Optional] string lpUNCServerName, string lpSourceName);
/// <summary>Writes an entry at the end of the specified event log.</summary>
/// <param name="hEventLog">
/// <para>A handle to the event log. The RegisterEventSource function returns this handle.</para>
/// <para>
/// As of Windows XP with SP2, this parameter cannot be a handle to the <c>Security</c> log. To write an event to the <c>Security</c>
/// log, use the AuthzReportSecurityEvent function.
/// </para>
/// </param>
/// <param name="wType">
/// <para>The type of event to be logged. This parameter can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>EVENTLOG_SUCCESS 0x0000</term>
/// <term>Information event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_AUDIT_FAILURE 0x0010</term>
/// <term>Failure Audit event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_AUDIT_SUCCESS 0x0008</term>
/// <term>Success Audit event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_ERROR_TYPE 0x0001</term>
/// <term>Error event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_INFORMATION_TYPE 0x0004</term>
/// <term>Information event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_WARNING_TYPE 0x0002</term>
/// <term>Warning event</term>
/// </item>
/// </list>
/// <para>For more information about event types, see Event Types.</para>
/// </param>
/// <param name="wCategory">
/// The event category. This is source-specific information; the category can have any value. For more information, see Event Categories.
/// </param>
/// <param name="dwEventID">
/// The event identifier. The event identifier specifies the entry in the message file associated with the event source. For more
/// information, see Event Identifiers.
/// </param>
/// <param name="lpUserSid">
/// A pointer to the current user's security identifier. This parameter can be <c>NULL</c> if the security identifier is not required.
/// </param>
/// <param name="wNumStrings">
/// The number of insert strings in the array pointed to by the lpStrings parameter. A value of zero indicates that no strings are present.
/// </param>
/// <param name="dwDataSize">
/// The number of bytes of event-specific raw (binary) data to write to the log. If this parameter is zero, no event-specific data is present.
/// </param>
/// <param name="lpStrings">
/// <para>
/// A pointer to a buffer containing an array of null-terminated strings that are merged into the message before Event Viewer
/// displays the string to the user. This parameter must be a valid pointer (or <c>NULL</c>), even if wNumStrings is zero. Each
/// string is limited to 31,839 characters.
/// </para>
/// <para><c>Prior to Windows Vista:</c> Each string is limited to 32K characters.</para>
/// </param>
/// <param name="lpRawData">
/// A pointer to the buffer containing the binary data. This parameter must be a valid pointer (or <c>NULL</c>), even if the
/// dwDataSize parameter is zero.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero, indicating that the entry was written to the log.</para>
/// <para>
/// If the function fails, the return value is zero. To get extended error information, call GetLastError, which returns one of the
/// following extended error codes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>
/// One of the parameters is not valid. This error is returned on Windows Server 2003 if the message data to be logged is too large.
/// This error is returned by the RPC server on Windows Server 2003 if the dwDataSize parameter is larger than 261,991 (0x3ff67).
/// </term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>Insufficient memory resources are available to complete the operation.</term>
/// </item>
/// <item>
/// <term>RPC_S_INVALID_BOUND</term>
/// <term>
/// The array bounds are invalid. This error is returned if the message data to be logged is too large. On Windows Vista and later,
/// this error is returned if the dwDataSize parameter is larger than 61,440 (0xf000).
/// </term>
/// </item>
/// <item>
/// <term>RPC_X_BAD_STUB_DATA</term>
/// <term>
/// The stub received bad data. This error is returned on Windows XP if the message data to be logged is too large. This error is
/// returned by the RPC server on Windows XP, if the dwDataSize parameter is larger than 262,143 (0x3ffff).
/// </term>
/// </item>
/// <item>
/// <term>Other</term>
/// <term>Use FormatMessage to obtain the message string for the returned error.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is used to log an event. The entry is written to the end of the configured log for the source identified by the
/// hEventLog parameter. The <c>ReportEvent</c> function adds the time, the entry's length, and the offsets before storing the entry
/// in the log. To enable the function to add the user name, you must supply the user's SID in the lpUserSid parameter.
/// </para>
/// <para>
/// There are different size limits on the size of the message data that can be logged depending on the version of Windows used by
/// both the client where the application is run and the server where the message is logged. The server is determined by the
/// lpUNCServerName parameter passed to the RegisterEventSource function. Different errors are returned when the size limit is
/// exceeded that depend on the version of Windows.
/// </para>
/// <para>
/// If the string that you log contains %n, where n is an integer value (for example, %1), the event viewer treats it as an insertion
/// string. Because an IPv6 address can contain this character sequence, you must provide a format specifier (!S!) to log an event
/// message that contains an IPv6 address. This specifier tells the formatting code to use the string literally and not perform any
/// further expansions (for example, "my IPv6 address is: %1!S!").
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Reporting an Event.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-reporteventa BOOL ReportEventA( HANDLE hEventLog, WORD
// wType, WORD wCategory, DWORD dwEventID, PSID lpUserSid, WORD wNumStrings, DWORD dwDataSize, LPCSTR *lpStrings, LPVOID lpRawData );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winbase.h", MSDNShortId = "e39273c3-9e42-41a1-9ec1-1cdff2ab7b55")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReportEvent(HEVENTLOG hEventLog, EVENTLOG_TYPE wType, ushort wCategory, uint dwEventID, PSID lpUserSid, ushort wNumStrings, uint dwDataSize, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPTStr, SizeParamIndex = 5)] string[] lpStrings, IntPtr lpRawData);
/// <summary>Indicates whether the event log is full.</summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_eventlog_full_information typedef struct
// _EVENTLOG_FULL_INFORMATION { DWORD dwFull; } EVENTLOG_FULL_INFORMATION, *LPEVENTLOG_FULL_INFORMATION;
[PInvokeData("winbase.h", MSDNShortId = "3ca41d6b-51a6-4226-89be-ab2c37628289")]
[StructLayout(LayoutKind.Sequential)]
public struct EVENTLOG_FULL_INFORMATION
{
/// <summary>Indicates whether the event log is full. If the log is full, this member is <c>TRUE</c>. Otherwise, it is <c>FALSE</c>.</summary>
[MarshalAs(UnmanagedType.Bool)]
public bool dwFull;
}
/// <summary>Provides a handle to an event log.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HEVENTLOG : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HEVENTLOG"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HEVENTLOG(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HEVENTLOG"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HEVENTLOG NULL => new HEVENTLOG(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="HEVENTLOG"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(HEVENTLOG h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HEVENTLOG"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HEVENTLOG(IntPtr h) => new HEVENTLOG(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HEVENTLOG h1, HEVENTLOG h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HEVENTLOG h1, HEVENTLOG h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is HEVENTLOG h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="HEVENTLOG"/> that is disposed using <see cref="CloseEventLog"/>.</summary>
public class SafeHEVENTLOG : SafeHANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeHEVENTLOG"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHEVENTLOG(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeHEVENTLOG"/> class.</summary>
private SafeHEVENTLOG() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeHEVENTLOG"/> to <see cref="HEVENTLOG"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HEVENTLOG(SafeHEVENTLOG h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => CloseEventLog(this);
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="HEVENTLOG"/> that is disposed using <see cref="DeregisterEventSource"/>.</summary>
public class SafeHEVENTSOURCE : SafeHANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeHEVENTSOURCE"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHEVENTSOURCE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeHEVENTSOURCE"/> class.</summary>
private SafeHEVENTSOURCE() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeHEVENTSOURCE"/> to <see cref="HEVENTLOG"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HEVENTLOG(SafeHEVENTSOURCE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => DeregisterEventSource(handle);
}
}
}