/// <summary>
        /// Register event log source
        /// </summary>
        /// <param name="sourceName">Name of the security event source</param>
        /// <param name="eventMessageFile">Full path to a resource DLL to interpret events in event viewer (optional)</param>
        /// <param name="eventSourceXmlSchemaFile"></param>
        /// <param name="eventAccessStringsFile"></param>
        /// <param name="executableImagePath">Full path to the executable file that is authorized to generate messages under this source name  (optional)</param>
        /// <param name="allowMultipleInstances">Flag indicating whether multiple instances of the process can log under this source name simultaneously</param>
        public static void InstallSecurityEventSource(
            string sourceName,
            string eventMessageFile,
            string eventSourceXmlSchemaFile,
            string eventAccessStringsFile,
            string executableImagePath,
            bool allowMultipleInstances)
        {
            if (sourceName == null)
            {
                throw new ArgumentNullException(nameof(sourceName));
            }

            if (!SourceNameValidator.IsSourceNameValid(sourceName))
            {
                throw new ArgumentException("Invalid event source name", nameof(sourceName));
            }

            try
            {
                Win32Native.AUTHZ_SOURCE_SCHEMA_REGISTRATION schema = new Win32Native.AUTHZ_SOURCE_SCHEMA_REGISTRATION();
                schema.dwFlags                          = allowMultipleInstances ? (uint)1 : (uint)0;
                schema.eventSourceName                  = sourceName;
                schema.eventMessageFile                 = eventMessageFile;
                schema.eventSourceXmlSchemaFile         = eventSourceXmlSchemaFile;
                schema.eventAccessStringsFile           = eventAccessStringsFile;
                schema.executableImagePath              = executableImagePath;
                schema.pReserved                        = IntPtr.Zero;
                schema.dwObjectTypeNameCount            = 0;
                schema.objectTypeNames.dwOffset         = 0;
                schema.objectTypeNames.szObjectTypeName = null;

                if (false == Win32Native.AuthzInstallSecurityEventSource(0, schema))
                {
                    int error = Marshal.GetLastWin32Error();

                    if (error == Win32Native.ERROR_NOT_ENOUGH_MEMORY)
                    {
                        throw new OutOfMemoryException();
                    }
                    else if (error == Win32Native.ERROR_ACCESS_DENIED)
                    {
                        throw new UnauthorizedAccessException();
                    }
                    else if (error == Win32Native.ERROR_OBJECT_ALREADY_EXISTS)
                    {
                        throw new InvalidOperationException("Event source already exists");
                    }
                    else
                    {
                        throw new Win32Exception(error);
                    }
                }
            }
            catch (EntryPointNotFoundException)
            {
                throw new NotSupportedException("Platform not supported");
            }
        }