using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
namespace Vanara.PInvoke
{
///
/// Formal replacement for the Windows HRESULT definition. In windows.h, it is a defined UINT value. For .NET, this class strongly types
/// the value.
/// The 32-bit value is organized as follows:
///
/// -
/// Bit
/// 31
/// 30
/// 29
/// 28
/// 27
/// 26 - 16
/// 15 - 0
///
/// -
/// Field
/// Severity
/// Severity
/// Customer
/// NT status
/// MsgID
/// Facility
/// Code
///
///
///
///
///
///
[StructLayout(LayoutKind.Sequential)]
[TypeConverter(typeof(HRESULTTypeConverter))]
[PInvokeData("winerr.h")]
public partial struct HRESULT : IComparable, IComparable, IEquatable, IEquatable, IEquatable, IConvertible, IErrorProvider
{
internal readonly int _value;
private const int codeMask = 0xFFFF;
private const uint facilityMask = 0x7FF0000;
private const int facilityShift = 16;
private const uint severityMask = 0x80000000;
private const int severityShift = 31;
/// Initializes a new instance of the structure.
/// The raw HRESULT value.
public HRESULT(int rawValue) => _value = rawValue;
/// Initializes a new instance of the structure.
/// The raw HRESULT value.
public HRESULT(uint rawValue) => _value = unchecked((int)rawValue);
/// Enumeration of facility codes
[PInvokeData("winerr.h")]
public enum FacilityCode
{
/// The default facility code.
FACILITY_NULL = 0,
/// The source of the error code is an RPC subsystem.
FACILITY_RPC = 1,
/// The source of the error code is a COM Dispatch.
FACILITY_DISPATCH = 2,
/// The source of the error code is OLE Storage.
FACILITY_STORAGE = 3,
/// The source of the error code is COM/OLE Interface management.
FACILITY_ITF = 4,
/// This region is reserved to map undecorated error codes into HRESULTs.
FACILITY_WIN32 = 7,
/// The source of the error code is the Windows subsystem.
FACILITY_WINDOWS = 8,
/// The source of the error code is the Security API layer.
FACILITY_SECURITY = 9,
/// The source of the error code is the Security API layer.
FACILITY_SSPI = 9,
/// The source of the error code is the control mechanism.
FACILITY_CONTROL = 10,
/// The source of the error code is a certificate client or server?
FACILITY_CERT = 11,
/// The source of the error code is Wininet related.
FACILITY_INTERNET = 12,
/// The source of the error code is the Windows Media Server.
FACILITY_MEDIASERVER = 13,
/// The source of the error code is the Microsoft Message Queue.
FACILITY_MSMQ = 14,
/// The source of the error code is the Setup API.
FACILITY_SETUPAPI = 15,
/// The source of the error code is the Smart-card subsystem.
FACILITY_SCARD = 16,
/// The source of the error code is COM+.
FACILITY_COMPLUS = 17,
/// The source of the error code is the Microsoft agent.
FACILITY_AAF = 18,
/// The source of the error code is .NET CLR.
FACILITY_URT = 19,
/// The source of the error code is the audit collection service.
FACILITY_ACS = 20,
/// The source of the error code is Direct Play.
FACILITY_DPLAY = 21,
/// The source of the error code is the ubiquitous memoryintrospection service.
FACILITY_UMI = 22,
/// The source of the error code is Side-by-side servicing.
FACILITY_SXS = 23,
/// The error code is specific to Windows CE.
FACILITY_WINDOWS_CE = 24,
/// The source of the error code is HTTP support.
FACILITY_HTTP = 25,
/// The source of the error code is common Logging support.
FACILITY_USERMODE_COMMONLOG = 26,
/// The source of the error code is the user mode filter manager.
FACILITY_USERMODE_FILTER_MANAGER = 31,
/// The source of the error code is background copy control
FACILITY_BACKGROUNDCOPY = 32,
/// The source of the error code is configuration services.
FACILITY_CONFIGURATION = 33,
/// The source of the error code is state management services.
FACILITY_STATE_MANAGEMENT = 34,
/// The source of the error code is the Microsoft Identity Server.
FACILITY_METADIRECTORY = 35,
/// The source of the error code is a Windows update.
FACILITY_WINDOWSUPDATE = 36,
/// The source of the error code is Active Directory.
FACILITY_DIRECTORYSERVICE = 37,
/// The source of the error code is the graphics drivers.
FACILITY_GRAPHICS = 38,
/// The source of the error code is the user Shell.
FACILITY_SHELL = 39,
/// The source of the error code is the Trusted Platform Module services.
FACILITY_TPM_SERVICES = 40,
/// The source of the error code is the Trusted Platform Module applications.
FACILITY_TPM_SOFTWARE = 41,
/// The source of the error code is Performance Logs and Alerts
FACILITY_PLA = 48,
/// The source of the error code is Full volume encryption.
FACILITY_FVE = 49,
/// The source of the error code is the Firewall Platform.
FACILITY_FWP = 50,
/// The source of the error code is the Windows Resource Manager.
FACILITY_WINRM = 51,
/// The source of the error code is the Network Driver Interface.
FACILITY_NDIS = 52,
/// The source of the error code is the Usermode Hypervisor components.
FACILITY_USERMODE_HYPERVISOR = 53,
/// The source of the error code is the Configuration Management Infrastructure.
FACILITY_CMI = 54,
/// The source of the error code is the user mode virtualization subsystem.
FACILITY_USERMODE_VIRTUALIZATION = 55,
/// The source of the error code is the user mode volume manager
FACILITY_USERMODE_VOLMGR = 56,
/// The source of the error code is the Boot Configuration Database.
FACILITY_BCD = 57,
/// The source of the error code is user mode virtual hard disk support.
FACILITY_USERMODE_VHD = 58,
/// The source of the error code is System Diagnostics.
FACILITY_SDIAG = 60,
/// The source of the error code is the Web Services.
FACILITY_WEBSERVICES = 61,
/// The source of the error code is a Windows Defender component.
FACILITY_WINDOWS_DEFENDER = 80,
/// The source of the error code is the open connectivity service.
FACILITY_OPC = 81,
///
FACILITY_XPS = 82,
///
FACILITY_MBN = 84,
///
FACILITY_POWERSHELL = 84,
///
FACILITY_RAS = 83,
///
FACILITY_P2P_INT = 98,
///
FACILITY_P2P = 99,
///
FACILITY_DAF = 100,
///
FACILITY_BLUETOOTH_ATT = 101,
///
FACILITY_AUDIO = 102,
///
FACILITY_STATEREPOSITORY = 103,
///
FACILITY_VISUALCPP = 109,
///
FACILITY_SCRIPT = 112,
///
FACILITY_PARSE = 113,
///
FACILITY_BLB = 120,
///
FACILITY_BLB_CLI = 121,
///
FACILITY_WSBAPP = 122,
///
FACILITY_BLBUI = 128,
///
FACILITY_USN = 129,
///
FACILITY_USERMODE_VOLSNAP = 130,
///
FACILITY_TIERING = 131,
///
FACILITY_WSB_ONLINE = 133,
///
FACILITY_ONLINE_ID = 134,
///
FACILITY_DEVICE_UPDATE_AGENT = 135,
///
FACILITY_DRVSERVICING = 136,
///
FACILITY_DLS = 153,
///
FACILITY_DELIVERY_OPTIMIZATION = 208,
///
FACILITY_USERMODE_SPACES = 231,
///
FACILITY_USER_MODE_SECURITY_CORE = 232,
///
FACILITY_USERMODE_LICENSING = 234,
///
FACILITY_SOS = 160,
///
FACILITY_DEBUGGERS = 176,
///
FACILITY_SPP = 256,
///
FACILITY_RESTORE = 256,
///
FACILITY_DMSERVER = 256,
///
FACILITY_DEPLOYMENT_SERVICES_SERVER = 257,
///
FACILITY_DEPLOYMENT_SERVICES_IMAGING = 258,
///
FACILITY_DEPLOYMENT_SERVICES_MANAGEMENT = 259,
///
FACILITY_DEPLOYMENT_SERVICES_UTIL = 260,
///
FACILITY_DEPLOYMENT_SERVICES_BINLSVC = 261,
///
FACILITY_DEPLOYMENT_SERVICES_PXE = 263,
///
FACILITY_DEPLOYMENT_SERVICES_TFTP = 264,
///
FACILITY_DEPLOYMENT_SERVICES_TRANSPORT_MANAGEMENT = 272,
///
FACILITY_DEPLOYMENT_SERVICES_DRIVER_PROVISIONING = 278,
///
FACILITY_DEPLOYMENT_SERVICES_MULTICAST_SERVER = 289,
///
FACILITY_DEPLOYMENT_SERVICES_MULTICAST_CLIENT = 290,
///
FACILITY_DEPLOYMENT_SERVICES_CONTENT_PROVIDER = 293,
///
FACILITY_LINGUISTIC_SERVICES = 305,
///
FACILITY_AUDIOSTREAMING = 1094,
///
FACILITY_ACCELERATOR = 1536,
///
FACILITY_WMAAECMA = 1996,
///
FACILITY_DIRECTMUSIC = 2168,
///
FACILITY_DIRECT3D10 = 2169,
///
FACILITY_DXGI = 2170,
///
FACILITY_DXGI_DDI = 2171,
///
FACILITY_DIRECT3D11 = 2172,
///
FACILITY_DIRECT3D11_DEBUG = 2173,
///
FACILITY_DIRECT3D12 = 2174,
///
FACILITY_DIRECT3D12_DEBUG = 2175,
///
FACILITY_LEAP = 2184,
///
FACILITY_AUDCLNT = 2185,
///
FACILITY_WINCODEC_DWRITE_DWM = 2200,
///
FACILITY_WINML = 2192,
///
FACILITY_DIRECT2D = 2201,
///
FACILITY_DEFRAG = 2304,
///
FACILITY_USERMODE_SDBUS = 2305,
///
FACILITY_JSCRIPT = 2306,
///
FACILITY_PIDGENX = 2561,
///
FACILITY_EAS = 85,
///
FACILITY_WEB = 885,
///
FACILITY_WEB_SOCKET = 886,
///
FACILITY_MOBILE = 1793,
///
FACILITY_SQLITE = 1967,
///
FACILITY_UTC = 1989,
///
FACILITY_WEP = 2049,
///
FACILITY_SYNCENGINE = 2050,
///
FACILITY_XBOX = 2339,
///
FACILITY_GAME = 2340,
///
FACILITY_PIX = 2748
}
/// A value indicating whether an is a success (Severity bit 31 equals 0).
[PInvokeData("winerr.h")]
public enum SeverityLevel
{
/// Success
Success = 0,
/// Failure
Fail = 1
}
/// Gets the code portion of the .
/// The code value (bits 0-15).
public int Code => GetCode(_value);
/// Gets the facility portion of the .
/// The facility value (bits 16-26).
public FacilityCode Facility => GetFacility(_value);
/// Gets a value indicating whether this is a failure (Severity bit 31 equals 1).
/// true if failed; otherwise, false.
public bool Failed => _value < 0;
/// Gets the severity level of the .
/// The severity level.
public SeverityLevel Severity => GetSeverity(_value);
/// Gets a value indicating whether this is a success (Severity bit 31 equals 0).
/// true if succeeded; otherwise, false.
public bool Succeeded => _value >= 0;
/// Performs an explicit conversion from to .
/// if set to returns S_OK; otherwise S_FALSE.
/// The result of the conversion.
public static explicit operator HRESULT(bool value) => value ? S_OK : S_FALSE;
/// Performs an explicit conversion from to .
/// The value.
/// The result of the conversion.
public static explicit operator int(HRESULT value) => value._value;
/// Performs an explicit conversion from to .
/// The value.
/// The result of the conversion.
public static explicit operator uint(HRESULT value) => unchecked((uint)value._value);
/// Tries to extract a HRESULT from an exception.
/// The exception.
/// The error. If undecipherable, E_FAIL is returned.
public static HRESULT FromException(Exception exception)
{
if (exception is Win32Exception we)
return new Win32Error(unchecked((uint)we.NativeErrorCode)).ToHRESULT();
if (exception.InnerException is Win32Exception iwe)
return new Win32Error(unchecked((uint)iwe.NativeErrorCode)).ToHRESULT();
#if !(NET20 || NET35 || NET40)
if (exception.HResult != 0)
return new HRESULT(exception.HResult);
else if (exception.InnerException != null && exception.InnerException.HResult != 0)
return new HRESULT(exception.InnerException.HResult);
#endif
return E_FAIL;
}
/// Gets the code value from a 32-bit value.
/// The 32-bit raw HRESULT value.
/// The code value (bits 0-15).
public static int GetCode(int hresult) => hresult & codeMask;
/// Gets the facility value from a 32-bit value.
/// The 32-bit raw HRESULT value.
/// The facility value (bits 16-26).
public static FacilityCode GetFacility(int hresult) => (FacilityCode)((hresult & facilityMask) >> facilityShift);
/// Gets the severity value from a 32-bit value.
/// The 32-bit raw HRESULT value.
/// The severity value (bit 31).
public static SeverityLevel GetSeverity(int hresult)
=> (SeverityLevel)((hresult & severityMask) >> severityShift);
/// Performs an implicit conversion from to .
/// The value.
/// The result of the conversion.
public static implicit operator HRESULT(int value) => new HRESULT(value);
/// Performs an implicit conversion from to .
/// The value.
/// The resulting instance from the conversion.
public static implicit operator HRESULT(uint value) => new HRESULT(value);
/// Maps an NT Status value to an HRESULT value.
/// The NT Status value.
/// The HRESULT value.
public static HRESULT HRESULT_FROM_NT(NTStatus err) => err.ToHRESULT();
/// Maps a system error code to an HRESULT value.
/// The system error code.
/// The HRESULT value.
public static HRESULT HRESULT_FROM_WIN32(Win32Error err) => err.ToHRESULT();
/// Creates a new from provided values.
/// if set to false, sets the severity bit to 1.
/// The facility.
/// The code.
/// The resulting .
public static HRESULT Make(bool severe, FacilityCode facility, uint code) => Make(severe, (uint)facility, code);
/// Creates a new from provided values.
/// if set to false, sets the severity bit to 1.
/// The facility.
/// The code.
/// The resulting .
public static HRESULT Make(bool severe, uint facility, uint code) =>
new HRESULT(unchecked((int)((severe ? severityMask : 0) | (facility << facilityShift) | code)));
/// Implements the operator !=.
/// The first .
/// The second .
/// The result of the operator.
public static bool operator !=(HRESULT hrLeft, HRESULT hrRight) => !(hrLeft == hrRight);
/// Implements the operator !=.
/// The first .
/// The second .
/// The result of the operator.
public static bool operator !=(HRESULT hrLeft, int hrRight) => !(hrLeft == hrRight);
/// Implements the operator !=.
/// The first .
/// The second .
/// The result of the operator.
public static bool operator !=(HRESULT hrLeft, uint hrRight) => !(hrLeft == hrRight);
/// Implements the operator ==.
/// The first .
/// The second .
/// The result of the operator.
public static bool operator ==(HRESULT hrLeft, HRESULT hrRight) => hrLeft.Equals(hrRight);
/// Implements the operator ==.
/// The first .
/// The second .
/// The result of the operator.
public static bool operator ==(HRESULT hrLeft, int hrRight) => hrLeft.Equals(hrRight);
/// Implements the operator ==.
/// The first .
/// The second .
/// The result of the operator.
public static bool operator ==(HRESULT hrLeft, uint hrRight) => hrLeft.Equals(hrRight);
///
/// If the supplied raw HRESULT value represents a failure, throw the associated with the optionally
/// supplied message.
///
/// The 32-bit raw HRESULT value.
/// The optional message to assign to the .
[System.Diagnostics.DebuggerStepThrough]
public static void ThrowIfFailed(int hresult, string message = null) => new HRESULT(hresult).ThrowIfFailed(message);
/// Compares the current object with another object of the same type.
/// An object to compare with this object.
///
/// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value
/// Meaning Less than zero This object is less than the parameter.Zero This object is equal to . Greater than zero This object is greater than .
///
public int CompareTo(HRESULT other) => _value.CompareTo(other._value);
///
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current
/// instance precedes, follows, or occurs in the same position in the sort order as the other object.
///
/// An object to compare with this instance.
///
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less
/// than zero This instance precedes in the sort order. Zero This instance occurs in the same position in the
/// sort order as . Greater than zero This instance follows in the sort order.
///
public int CompareTo(object obj)
{
var v = ValueFromObj(obj);
return v.HasValue
? _value.CompareTo(v.Value)
: throw new ArgumentException(@"Object cannot be converted to a UInt32 value for comparison.", nameof(obj));
}
/// Indicates whether the current object is equal to an .
/// An object to compare with this object.
/// true if the current object is equal to the parameter; otherwise, false.
public bool Equals(int other) => other == _value;
/// Indicates whether the current object is equal to an .
/// An object to compare with this object.
/// true if the current object is equal to the parameter; otherwise, false.
public bool Equals(uint other) => unchecked((int)other) == _value;
/// Determines whether the specified , is equal to this instance.
/// The to compare with this instance.
/// true if the specified is equal to this instance; otherwise, false.
public override bool Equals(object obj) => obj switch
{
null => false,
HRESULT h => Equals(h),
int i => Equals(i),
uint u => Equals(u),
_ => Equals(_value, ValueFromObj(obj)),
};
/// Indicates whether the current object is equal to another object of the same type.
/// An object to compare with this object.
/// true if the current object is equal to the parameter; otherwise, false.
public bool Equals(HRESULT other) => other._value == _value;
/// Gets the .NET associated with the HRESULT value and optionally adds the supplied message.
/// The optional message to assign to the .
/// The associated or null if this HRESULT is not a failure.
[SecurityCritical, SecuritySafeCritical]
public Exception GetException(string message = null)
{
if (!Failed) return null;
var exceptionForHR = Marshal.GetExceptionForHR(_value, new IntPtr(-1));
if (exceptionForHR.GetType() == typeof(COMException))
{
if (Facility == FacilityCode.FACILITY_WIN32)
return string.IsNullOrEmpty(message) ? new Win32Exception(Code) : new Win32Exception(Code, message);
return new COMException(message ?? exceptionForHR.Message, _value);
}
if (!string.IsNullOrEmpty(message))
{
Type[] types = { typeof(string) };
var constructor = exceptionForHR.GetType().GetConstructor(types);
if (null != constructor)
{
object[] parameters = { message };
exceptionForHR = constructor.Invoke(parameters) as Exception;
}
}
return exceptionForHR;
}
/// Returns a hash code for this instance.
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
public override int GetHashCode() => _value;
///
/// If this represents a failure, throw the associated with the optionally supplied message.
///
/// The optional message to assign to the .
[SecurityCritical, SecuritySafeCritical]
[System.Diagnostics.DebuggerStepThrough]
public void ThrowIfFailed(string message = null)
{
var exception = GetException(message);
if (exception != null)
throw exception;
}
/// Returns a that represents this instance.
/// A that represents this instance.
public override string ToString()
{
string err = null;
// Check for defined HRESULT value
if (!StaticFieldValueHash.TryGetFieldName(_value, out err) && Facility == FacilityCode.FACILITY_WIN32)
{
foreach (var info2 in typeof(Win32Error).GetFields(BindingFlags.Public | BindingFlags.Static).Where(fi => fi.FieldType == typeof(uint)))
{
if ((HRESULT)(Win32Error)(uint)info2.GetValue(null) == this)
{
err = $"HRESULT_FROM_WIN32({info2.Name})";
break;
}
}
}
var msg = FormatMessage(unchecked((uint)_value));
return (err ?? string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", _value)) + (msg == null ? "" : ": " + msg);
}
TypeCode IConvertible.GetTypeCode() => _value.GetTypeCode();
bool IConvertible.ToBoolean(IFormatProvider provider) => Succeeded;
byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)_value).ToByte(provider);
char IConvertible.ToChar(IFormatProvider provider) => throw new NotSupportedException();
DateTime IConvertible.ToDateTime(IFormatProvider provider) => throw new NotSupportedException();
decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)_value).ToDecimal(provider);
double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)_value).ToDouble(provider);
/// Converts this error to an .
/// An equivalent .
HRESULT IErrorProvider.ToHRESULT() => this;
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)_value).ToInt16(provider);
int IConvertible.ToInt32(IFormatProvider provider) => _value;
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)_value).ToInt64(provider);
sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)_value).ToSByte(provider);
float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)_value).ToSingle(provider);
string IConvertible.ToString(IFormatProvider provider) => ToString();
object IConvertible.ToType(Type conversionType, IFormatProvider provider) =>
((IConvertible)_value).ToType(conversionType, provider);
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)unchecked((uint)_value)).ToUInt16(provider);
uint IConvertible.ToUInt32(IFormatProvider provider) => unchecked((uint)_value);
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)unchecked((uint)_value)).ToUInt64(provider);
/// Formats the message.
/// The error.
/// The string.
internal static string FormatMessage(uint id)
{
var flags = 0x1200U; // FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM
var buf = new System.Text.StringBuilder(1024);
do
{
if (0 != FormatMessage(flags, default, id, 0, buf, (uint)buf.Capacity, default))
return buf.ToString();
var lastError = Win32Error.GetLastError();
if (lastError == Win32Error.ERROR_MR_MID_NOT_FOUND || lastError == Win32Error.ERROR_MUI_FILE_NOT_FOUND)
break;
if (lastError != Win32Error.ERROR_INSUFFICIENT_BUFFER)
lastError.ThrowIfFailed();
buf.Capacity *= 2;
} while (true && buf.Capacity < 1024 * 16); // Don't go crazy
return string.Empty;
}
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
private static extern int FormatMessage(uint dwFlags, HINSTANCE lpSource, uint dwMessageId, uint dwLanguageId, System.Text.StringBuilder lpBuffer, uint nSize, IntPtr Arguments);
private static int? ValueFromObj(object obj)
{
switch (obj)
{
case null:
return null;
case int i:
return i;
case uint u:
return unchecked((int)u);
default:
var c = TypeDescriptor.GetConverter(obj);
return c.CanConvertTo(typeof(int)) ? (int?)c.ConvertTo(obj, typeof(int)) : null;
}
}
}
internal class HRESULTTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(Win32Error) || sourceType.IsPrimitive && sourceType != typeof(char))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string) || destinationType.IsPrimitive && destinationType != typeof(char))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is Win32Error e)
return e.ToHRESULT();
if (value != null && value.GetType().IsPrimitive)
{
if (value is bool b)
return b ? HRESULT.S_OK : HRESULT.S_FALSE;
if (!(value is char))
return new HRESULT((int)Convert.ChangeType(value, TypeCode.Int32));
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value,
Type destinationType)
{
if (!(value is HRESULT hr)) throw new NotSupportedException();
if (destinationType.IsPrimitive && destinationType != typeof(char))
return Convert.ChangeType(hr, destinationType);
if (destinationType == typeof(string))
return hr.ToString();
return base.ConvertTo(context, culture, value, destinationType);
}
}
}