Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / TypeNameParser.cs / 1305376 / TypeNameParser.cs
using System; using System.Diagnostics.Contracts; using System.IO; using System.Reflection; using System.Security; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; #if !FEATURE_CORECLR namespace System { [SecurityCritical] internal class SafeTypeNameParserHandle : SafeHandleZeroOrMinusOneIsInvalid { #region QCalls [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _ReleaseTypeNameParser(IntPtr pTypeNameParser); #endregion public SafeTypeNameParserHandle() : base(true) { } [SecurityCritical] protected override bool ReleaseHandle() { _ReleaseTypeNameParser(handle); handle = IntPtr.Zero; return true; } } internal sealed class TypeNameParser : IDisposable { #region QCalls [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _CreateTypeNameParser(string typeName, ObjectHandleOnStack retHandle, bool throwOnError); [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _GetNames(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray); [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _GetTypeArguments(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray); [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _GetModifiers(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray); [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _GetAssemblyName(SafeTypeNameParserHandle pTypeNameParser, StringHandleOnStack retString); #endregion #region Static Members [SecuritySafeCritical] internal static Type GetType( string typeName, FuncassemblyResolver, Func typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark) { if (typeName == null) throw new ArgumentNullException("typeName"); if (typeName.Length > 0 && typeName[0] == '\0') throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength")); Contract.EndContractBlock(); Type ret = null; SafeTypeNameParserHandle handle = CreateTypeNameParser(typeName, throwOnError); if (handle != null) { // If we get here the typeName must have been successfully parsed. // Let's construct the Type object. using (TypeNameParser parser = new TypeNameParser(handle)) { ret = parser.ConstructType(assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark); } } return ret; } #endregion #region Private Data Members private SafeTypeNameParserHandle m_NativeParser; private static readonly char[] SPECIAL_CHARS = {',', '[', ']', '&', '*', '+', '\\'}; /* see typeparse.h */ #endregion #region Constructor and Disposer [SecuritySafeCritical] private TypeNameParser(SafeTypeNameParserHandle handle) { m_NativeParser = handle; } [SecuritySafeCritical] public void Dispose() { m_NativeParser.Dispose(); } #endregion #region private Members [SecuritySafeCritical] private unsafe Type ConstructType( Func assemblyResolver, Func typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark) { // assembly name Assembly assembly = null; string asmName = GetAssemblyName(); // GetAssemblyName never returns null Contract.Assert(asmName != null); if (asmName.Length > 0) { assembly = ResolveAssembly(asmName, assemblyResolver, throwOnError, ref stackMark); if (assembly == null) { // Cannot resolve the assembly. If throwOnError is true we should have already thrown. return null; } } string[] names = GetNames(); if (names == null) { // This can only happen if the type name is an empty string or if the first char is '\0' if (throwOnError) throw new TypeLoadException(Environment.GetResourceString("Arg_TypeLoadNullStr")); return null; } Type baseType = ResolveType(assembly, names, typeResolver, throwOnError, ignoreCase, ref stackMark); if (baseType == null) { // Cannot resolve the type. If throwOnError is true we should have already thrown. Contract.Assert(throwOnError == false); return null; } SafeTypeNameParserHandle[] typeArguments = GetTypeArguments(); Type[] types = null; if (typeArguments != null) { types = new Type[typeArguments.Length]; for (int i = 0; i < typeArguments.Length; i++) { Contract.Assert(typeArguments[i] != null); using (TypeNameParser argParser = new TypeNameParser(typeArguments[i])) { types[i] = argParser.ConstructType(assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark); } if (types[i] == null) { // If throwOnError is true argParser.ConstructType should have already thrown. Contract.Assert(throwOnError == false); return null; } } } int[] modifiers = GetModifiers(); fixed (int* ptr = modifiers) { IntPtr intPtr = new IntPtr(ptr); return RuntimeTypeHandle.GetTypeHelper(baseType, types, intPtr, modifiers == null ? 0 : modifiers.Length); } } [SecuritySafeCritical] private static Assembly ResolveAssembly(string asmName, Func assemblyResolver, bool throwOnError, ref StackCrawlMark stackMark) { Contract.Requires(asmName != null && asmName.Length > 0); Assembly assembly = null; if (assemblyResolver == null) { if (throwOnError) { assembly = RuntimeAssembly.InternalLoad(asmName, null, ref stackMark, false /*forIntrospection*/); } else { // When throwOnError is false we should only catch FileNotFoundException. // Other exceptions like BadImangeFormatException should still fly. try { assembly = RuntimeAssembly.InternalLoad(asmName, null, ref stackMark, false /*forIntrospection*/); } catch (FileNotFoundException) { return null; } } } else { assembly = assemblyResolver(new AssemblyName(asmName)); if (assembly == null && throwOnError) { throw new FileNotFoundException(Environment.GetResourceString("FileNotFound_ResolveAssembly", asmName)); } } return assembly; } private static Type ResolveType(Assembly assembly, string[] names, Func typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark) { Contract.Requires(names != null && names.Length > 0); Type type = null; // both the customer provided and the default type resolvers accept escaped type names string OuterMostTypeName = EscapeTypeName(names[0]); // Resolve the top level type. if (typeResolver != null) { type = typeResolver(assembly, OuterMostTypeName, ignoreCase); if (type == null && throwOnError) { string errorString = assembly == null ? Environment.GetResourceString("TypeLoad_ResolveType", OuterMostTypeName) : Environment.GetResourceString("TypeLoad_ResolveTypeFromAssembly", OuterMostTypeName, assembly.FullName); throw new TypeLoadException(errorString); } } else { if (assembly == null) { type = RuntimeType.GetType(OuterMostTypeName, throwOnError, ignoreCase, false, ref stackMark); } else { type = assembly.GetType(OuterMostTypeName, throwOnError, ignoreCase); } } // Resolve nested types. if (type != null) { BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public; if (ignoreCase) bindingFlags |= BindingFlags.IgnoreCase; for (int i = 1; i < names.Length; i++) { type = type.GetNestedType(names[i], bindingFlags); if (type == null) { if (throwOnError) throw new TypeLoadException(Environment.GetResourceString("TypeLoad_ResolveNestedType", names[i], names[i-1])); else break; } } } return type; } private static string EscapeTypeName(string name) { if (name.IndexOfAny(SPECIAL_CHARS) < 0) return name; StringBuilder sb = new StringBuilder(); foreach (char c in name) { if (Array.IndexOf (SPECIAL_CHARS, c) >= 0) sb.Append('\\'); sb.Append(c); } return sb.ToString(); } [SecuritySafeCritical] private static SafeTypeNameParserHandle CreateTypeNameParser(string typeName, bool throwOnError) { SafeTypeNameParserHandle retHandle = null; _CreateTypeNameParser(typeName, JitHelpers.GetObjectHandleOnStack(ref retHandle), throwOnError); return retHandle; } [SecuritySafeCritical] private string[] GetNames() { string[] names = null; _GetNames(m_NativeParser, JitHelpers.GetObjectHandleOnStack(ref names)); return names; } [SecuritySafeCritical] private SafeTypeNameParserHandle[] GetTypeArguments() { SafeTypeNameParserHandle[] arguments = null; _GetTypeArguments(m_NativeParser, JitHelpers.GetObjectHandleOnStack(ref arguments)); return arguments; } [SecuritySafeCritical] private int[] GetModifiers() { int[] modifiers = null; _GetModifiers(m_NativeParser, JitHelpers.GetObjectHandleOnStack(ref modifiers)); return modifiers; } [SecuritySafeCritical] private string GetAssemblyName() { string assemblyName = null; _GetAssemblyName(m_NativeParser, JitHelpers.GetStringHandleOnStack(ref assemblyName)); return assemblyName; } #endregion } } #endif //!FEATURE_CORECLR // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Diagnostics.Contracts; using System.IO; using System.Reflection; using System.Security; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; #if !FEATURE_CORECLR namespace System { [SecurityCritical] internal class SafeTypeNameParserHandle : SafeHandleZeroOrMinusOneIsInvalid { #region QCalls [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _ReleaseTypeNameParser(IntPtr pTypeNameParser); #endregion public SafeTypeNameParserHandle() : base(true) { } [SecurityCritical] protected override bool ReleaseHandle() { _ReleaseTypeNameParser(handle); handle = IntPtr.Zero; return true; } } internal sealed class TypeNameParser : IDisposable { #region QCalls [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _CreateTypeNameParser(string typeName, ObjectHandleOnStack retHandle, bool throwOnError); [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _GetNames(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray); [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _GetTypeArguments(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray); [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _GetModifiers(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray); [SecurityCritical] [ResourceExposure(ResourceScope.None)] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] private static extern void _GetAssemblyName(SafeTypeNameParserHandle pTypeNameParser, StringHandleOnStack retString); #endregion #region Static Members [SecuritySafeCritical] internal static Type GetType( string typeName, Func assemblyResolver, Func typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark) { if (typeName == null) throw new ArgumentNullException("typeName"); if (typeName.Length > 0 && typeName[0] == '\0') throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength")); Contract.EndContractBlock(); Type ret = null; SafeTypeNameParserHandle handle = CreateTypeNameParser(typeName, throwOnError); if (handle != null) { // If we get here the typeName must have been successfully parsed. // Let's construct the Type object. using (TypeNameParser parser = new TypeNameParser(handle)) { ret = parser.ConstructType(assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark); } } return ret; } #endregion #region Private Data Members private SafeTypeNameParserHandle m_NativeParser; private static readonly char[] SPECIAL_CHARS = {',', '[', ']', '&', '*', '+', '\\'}; /* see typeparse.h */ #endregion #region Constructor and Disposer [SecuritySafeCritical] private TypeNameParser(SafeTypeNameParserHandle handle) { m_NativeParser = handle; } [SecuritySafeCritical] public void Dispose() { m_NativeParser.Dispose(); } #endregion #region private Members [SecuritySafeCritical] private unsafe Type ConstructType( Func assemblyResolver, Func typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark) { // assembly name Assembly assembly = null; string asmName = GetAssemblyName(); // GetAssemblyName never returns null Contract.Assert(asmName != null); if (asmName.Length > 0) { assembly = ResolveAssembly(asmName, assemblyResolver, throwOnError, ref stackMark); if (assembly == null) { // Cannot resolve the assembly. If throwOnError is true we should have already thrown. return null; } } string[] names = GetNames(); if (names == null) { // This can only happen if the type name is an empty string or if the first char is '\0' if (throwOnError) throw new TypeLoadException(Environment.GetResourceString("Arg_TypeLoadNullStr")); return null; } Type baseType = ResolveType(assembly, names, typeResolver, throwOnError, ignoreCase, ref stackMark); if (baseType == null) { // Cannot resolve the type. If throwOnError is true we should have already thrown. Contract.Assert(throwOnError == false); return null; } SafeTypeNameParserHandle[] typeArguments = GetTypeArguments(); Type[] types = null; if (typeArguments != null) { types = new Type[typeArguments.Length]; for (int i = 0; i < typeArguments.Length; i++) { Contract.Assert(typeArguments[i] != null); using (TypeNameParser argParser = new TypeNameParser(typeArguments[i])) { types[i] = argParser.ConstructType(assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark); } if (types[i] == null) { // If throwOnError is true argParser.ConstructType should have already thrown. Contract.Assert(throwOnError == false); return null; } } } int[] modifiers = GetModifiers(); fixed (int* ptr = modifiers) { IntPtr intPtr = new IntPtr(ptr); return RuntimeTypeHandle.GetTypeHelper(baseType, types, intPtr, modifiers == null ? 0 : modifiers.Length); } } [SecuritySafeCritical] private static Assembly ResolveAssembly(string asmName, Func assemblyResolver, bool throwOnError, ref StackCrawlMark stackMark) { Contract.Requires(asmName != null && asmName.Length > 0); Assembly assembly = null; if (assemblyResolver == null) { if (throwOnError) { assembly = RuntimeAssembly.InternalLoad(asmName, null, ref stackMark, false /*forIntrospection*/); } else { // When throwOnError is false we should only catch FileNotFoundException. // Other exceptions like BadImangeFormatException should still fly. try { assembly = RuntimeAssembly.InternalLoad(asmName, null, ref stackMark, false /*forIntrospection*/); } catch (FileNotFoundException) { return null; } } } else { assembly = assemblyResolver(new AssemblyName(asmName)); if (assembly == null && throwOnError) { throw new FileNotFoundException(Environment.GetResourceString("FileNotFound_ResolveAssembly", asmName)); } } return assembly; } private static Type ResolveType(Assembly assembly, string[] names, Func typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark) { Contract.Requires(names != null && names.Length > 0); Type type = null; // both the customer provided and the default type resolvers accept escaped type names string OuterMostTypeName = EscapeTypeName(names[0]); // Resolve the top level type. if (typeResolver != null) { type = typeResolver(assembly, OuterMostTypeName, ignoreCase); if (type == null && throwOnError) { string errorString = assembly == null ? Environment.GetResourceString("TypeLoad_ResolveType", OuterMostTypeName) : Environment.GetResourceString("TypeLoad_ResolveTypeFromAssembly", OuterMostTypeName, assembly.FullName); throw new TypeLoadException(errorString); } } else { if (assembly == null) { type = RuntimeType.GetType(OuterMostTypeName, throwOnError, ignoreCase, false, ref stackMark); } else { type = assembly.GetType(OuterMostTypeName, throwOnError, ignoreCase); } } // Resolve nested types. if (type != null) { BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public; if (ignoreCase) bindingFlags |= BindingFlags.IgnoreCase; for (int i = 1; i < names.Length; i++) { type = type.GetNestedType(names[i], bindingFlags); if (type == null) { if (throwOnError) throw new TypeLoadException(Environment.GetResourceString("TypeLoad_ResolveNestedType", names[i], names[i-1])); else break; } } } return type; } private static string EscapeTypeName(string name) { if (name.IndexOfAny(SPECIAL_CHARS) < 0) return name; StringBuilder sb = new StringBuilder(); foreach (char c in name) { if (Array.IndexOf (SPECIAL_CHARS, c) >= 0) sb.Append('\\'); sb.Append(c); } return sb.ToString(); } [SecuritySafeCritical] private static SafeTypeNameParserHandle CreateTypeNameParser(string typeName, bool throwOnError) { SafeTypeNameParserHandle retHandle = null; _CreateTypeNameParser(typeName, JitHelpers.GetObjectHandleOnStack(ref retHandle), throwOnError); return retHandle; } [SecuritySafeCritical] private string[] GetNames() { string[] names = null; _GetNames(m_NativeParser, JitHelpers.GetObjectHandleOnStack(ref names)); return names; } [SecuritySafeCritical] private SafeTypeNameParserHandle[] GetTypeArguments() { SafeTypeNameParserHandle[] arguments = null; _GetTypeArguments(m_NativeParser, JitHelpers.GetObjectHandleOnStack(ref arguments)); return arguments; } [SecuritySafeCritical] private int[] GetModifiers() { int[] modifiers = null; _GetModifiers(m_NativeParser, JitHelpers.GetObjectHandleOnStack(ref modifiers)); return modifiers; } [SecuritySafeCritical] private string GetAssemblyName() { string assemblyName = null; _GetAssemblyName(m_NativeParser, JitHelpers.GetStringHandleOnStack(ref assemblyName)); return assemblyName; } #endregion } } #endif //!FEATURE_CORECLR // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SerializationEventsCache.cs
- GenericParameterDataContract.cs
- KoreanLunisolarCalendar.cs
- CodeIndexerExpression.cs
- SerializationFieldInfo.cs
- XmlSignificantWhitespace.cs
- BehaviorService.cs
- ListViewEditEventArgs.cs
- MatcherBuilder.cs
- MetadataArtifactLoaderFile.cs
- BitmapDownload.cs
- NativeMethods.cs
- VectorCollection.cs
- TextViewBase.cs
- KoreanLunisolarCalendar.cs
- SecurityImpersonationBehavior.cs
- WpfPayload.cs
- InfoCardClaimCollection.cs
- SqlDataSourceQuery.cs
- PasswordBoxAutomationPeer.cs
- ToolStripLocationCancelEventArgs.cs
- StreamWriter.cs
- ComponentDispatcherThread.cs
- VisemeEventArgs.cs
- PixelFormat.cs
- MemberHolder.cs
- ECDiffieHellman.cs
- TemplateBindingExtensionConverter.cs
- DesignerTransaction.cs
- ToolboxControl.cs
- FileChangesMonitor.cs
- WebPartsPersonalizationAuthorization.cs
- SizeFConverter.cs
- Window.cs
- EntityConnection.cs
- Crypto.cs
- UidManager.cs
- ErrorInfoXmlDocument.cs
- ObjectPersistData.cs
- FileSecurity.cs
- ThreadAbortException.cs
- ReversePositionQuery.cs
- DefaultParameterValueAttribute.cs
- BuilderPropertyEntry.cs
- _NegoState.cs
- AxHostDesigner.cs
- UserNameSecurityTokenProvider.cs
- ChtmlCalendarAdapter.cs
- ConfigXmlComment.cs
- Visual3D.cs
- odbcmetadatacollectionnames.cs
- PersianCalendar.cs
- HelloMessageCD1.cs
- DataGrid.cs
- QueryCacheKey.cs
- ManualResetEvent.cs
- _SecureChannel.cs
- CalendarAutomationPeer.cs
- Speller.cs
- UserControlAutomationPeer.cs
- BlurBitmapEffect.cs
- WorkflowServiceNamespace.cs
- DataGridRowHeader.cs
- DataServiceException.cs
- CodeObject.cs
- SafeCertificateContext.cs
- SurrogateEncoder.cs
- StreamResourceInfo.cs
- SubstitutionList.cs
- SqlDataSourceStatusEventArgs.cs
- SelectionHighlightInfo.cs
- URLAttribute.cs
- Image.cs
- FamilyMap.cs
- SHA256.cs
- Soap.cs
- Task.cs
- UIPermission.cs
- SubMenuStyleCollectionEditor.cs
- PropertyRecord.cs
- NumberSubstitution.cs
- EventSourceCreationData.cs
- XmlSchemaSimpleTypeUnion.cs
- InfoCardArgumentException.cs
- BrowserDefinitionCollection.cs
- RijndaelManagedTransform.cs
- DependencySource.cs
- MetadataException.cs
- sqlser.cs
- DbRetry.cs
- QilGenerator.cs
- TraversalRequest.cs
- RelatedView.cs
- _DomainName.cs
- InfiniteTimeSpanConverter.cs
- DataGridViewTextBoxEditingControl.cs
- PageBreakRecord.cs
- URLString.cs
- EntityTypeEmitter.cs
- GridSplitterAutomationPeer.cs