#region Apache License // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to you under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #endregion // MONO 1.0 has no support for Win32 Error APIs #if !MONO // SSCLI 1.0 has no support for Win32 Error APIs #if !SSCLI // We don't want framework or platform specific code in the CLI version of log4net #if !CLI_1_0 using System; using System.Globalization; using System.Runtime.InteropServices; namespace log4net.Util { /// /// Represents a native error code and message. /// /// /// /// Represents a Win32 platform native error. /// /// /// Nicko Cadell /// Gert Driesen public sealed class NativeError { #region Protected Instance Constructors /// /// Create an instance of the class with the specified /// error number and message. /// /// The number of the native error. /// The message of the native error. /// /// /// Create an instance of the class with the specified /// error number and message. /// /// private NativeError(int number, string message) { m_number = number; m_message = message; } #endregion // Protected Instance Constructors #region Public Instance Properties /// /// Gets the number of the native error. /// /// /// The number of the native error. /// /// /// /// Gets the number of the native error. /// /// public int Number { get { return m_number; } } /// /// Gets the message of the native error. /// /// /// The message of the native error. /// /// /// /// /// Gets the message of the native error. /// public string Message { get { return m_message; } } #endregion // Public Instance Properties #region Public Static Methods /// /// Create a new instance of the class for the last Windows error. /// /// /// An instance of the class for the last windows error. /// /// /// /// The message for the error number is lookup up using the /// native Win32 FormatMessage function. /// /// #if NET_4_0 [System.Security.SecuritySafeCritical] #elif !NETCF [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode=true)] #endif public static NativeError GetLastError() { int number = Marshal.GetLastWin32Error(); return new NativeError(number, NativeError.GetErrorMessage(number)); } /// /// Create a new instance of the class. /// /// the error number for the native error /// /// An instance of the class for the specified /// error number. /// /// /// /// The message for the specified error number is lookup up using the /// native Win32 FormatMessage function. /// /// public static NativeError GetError(int number) { return new NativeError(number, NativeError.GetErrorMessage(number)); } /// /// Retrieves the message corresponding with a Win32 message identifier. /// /// Message identifier for the requested message. /// /// The message corresponding with the specified message identifier. /// /// /// /// The message will be searched for in system message-table resource(s) /// using the native FormatMessage function. /// /// #if NET_4_0 [System.Security.SecuritySafeCritical] #elif !NETCF [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, UnmanagedCode = true)] #endif public static string GetErrorMessage(int messageId) { // Win32 constants int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; // The function should allocates a buffer large enough to hold the formatted message int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; // Insert sequences in the message definition are to be ignored int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; // The function should search the system message-table resource(s) for the requested message string msgBuf = ""; // buffer that will receive the message IntPtr sourcePtr = new IntPtr(); // Location of the message definition, will be ignored IntPtr argumentsPtr = new IntPtr(); // Pointer to array of values to insert, not supported as it requires unsafe code if (messageId != 0) { // If the function succeeds, the return value is the number of TCHARs stored in the output buffer, excluding the terminating null character int messageSize = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, ref sourcePtr, messageId, 0, ref msgBuf, 255, argumentsPtr); if (messageSize > 0) { // Remove trailing null-terminating characters (\r\n) from the message msgBuf = msgBuf.TrimEnd(new char[] {'\r', '\n'}); } else { // A message could not be located. msgBuf = null; } } else { msgBuf = null; } return msgBuf; } #endregion // Public Static Methods #region Override Object Implementation /// /// Return error information string /// /// error information string /// /// /// Return error information string /// /// public override string ToString() { return string.Format(CultureInfo.InvariantCulture, "0x{0:x8}", this.Number) + (this.Message != null ? ": " + this.Message : ""); } #endregion // Override Object Implementation #region Stubs For Native Function Calls /// /// Formats a message string. /// /// Formatting options, and how to interpret the parameter. /// Location of the message definition. /// Message identifier for the requested message. /// Language identifier for the requested message. /// If includes FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer using the LocalAlloc function, and places the pointer to the buffer at the address specified in . /// If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies the maximum number of TCHARs that can be stored in the output buffer. If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies the minimum number of TCHARs to allocate for an output buffer. /// Pointer to an array of values that are used as insert values in the formatted message. /// /// /// The function requires a message definition as input. The message definition can come from a /// buffer passed into the function. It can come from a message table resource in an /// already-loaded module. Or the caller can ask the function to search the system's message /// table resource(s) for the message definition. The function finds the message definition /// in a message table resource based on a message identifier and a language identifier. /// The function copies the formatted message text to an output buffer, processing any embedded /// insert sequences if requested. /// /// /// To prevent the usage of unsafe code, this stub does not support inserting values in the formatted message. /// /// /// /// /// If the function succeeds, the return value is the number of TCHARs stored in the output /// buffer, excluding the terminating null character. /// /// /// If the function fails, the return value is zero. To get extended error information, /// call . /// /// #if NETCF [DllImport("CoreDll.dll", SetLastError=true, CharSet=CharSet.Unicode)] #else [DllImport("Kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)] #endif private static extern int FormatMessage( int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr Arguments); #endregion // Stubs For Native Function Calls #region Private Instance Fields private int m_number; private string m_message; #endregion } } #endif // !CLI_1_0 #endif // !SSCLI #endif // !MONO