Partilhar via


CA1060: Mover P/Invokes NativeMethods classe

TypeName

MovePInvokesToNativeMethodsClass

CheckId

CA1060

<strong>Categoria</strong>

Microsoft.design

Alteração significativa

Quebrando

Causa

Um método usa o serviços de invocação de plataforma para acessar código não gerenciado e não é um membro de um da NativeMethods classes.

Descrição da regra

Métodos de invocação de plataforma, tais como aquelas que são marcadas usando o System.Runtime.InteropServices.DllImportAttribute atributo ou métodos que são definidos usando o Declare palavra-chave em Visual Basic, acessar código não gerenciado. Esses métodos devem ser em uma das seguintes classes:

  • NativeMethods -esta classe não suprime as movimentações de pilha para permissão de código não gerenciado. (System.Security.SuppressUnmanagedCodeSecurityAttribute não deve ser aplicado a essa classe.) Essa classe é para os métodos que podem ser usados em qualquer lugar, porque uma stack walk será executada.

  • SafeNativeMethods -esta classe suprime as movimentações de pilha para permissão de código não gerenciado. (System.Security.SuppressUnmanagedCodeSecurityAttribute é aplicado a essa classe.) Essa classe é para métodos que são seguros para qualquer pessoa chamada. Não, os chamadores desses métodos são necessários para realizar uma análise de segurança máxima para certificar-se de que o uso é seguro porque os métodos são inofensivos para qualquer chamador.

  • UnsafeNativeMethods -esta classe suprime as movimentações de pilha para permissão de código não gerenciado. (System.Security.SuppressUnmanagedCodeSecurityAttribute é aplicado a essa classe.) Essa classe é para os métodos são potencialmente perigosos. Qualquer chamador destes métodos deverá executar uma análise de segurança completo para certificar-se de que o uso é seguro porque nenhuma stack walk será executada.

Essas classes são declaradas como internal (Friend, em Visual Basic) e declara um construtor particular para impedir que novas instâncias que está sendo criado. Os métodos nessas classes devem ser static e internal (Shared e Friend em Visual Basic).

Como corrigir violações

Para corrigir uma violação desta regra, mover o método para o apropriado NativeMethods classe. Para a maioria dos aplicativos, movendo P/Invokes para uma nova classe chamada NativeMethods é suficiente.

No entanto, se você estiver desenvolvendo bibliotecas para uso em outros aplicativos, você deverá considerar a definição duas classes que são chamados de SafeNativeMethods e UnsafeNativeMethods. Essas classes é semelhante a NativeMethods de classe; No entanto, eles são marcados usando um atributo especial chamado SuppressUnmanagedCodeSecurityAttribute. Quando esse atributo é aplicado, o runtime não realiza um stack walk completo para certificar-se de que todos os chamadores têm a UnmanagedCode permissão. Normalmente, o runtime verifica essa permissão na inicialização. Como a verificação não é executada, ela pode melhorar muito o desempenho para chamadas para esses métodos não gerenciados, ele também permite que o código que tenha permissões para chamar esses métodos limitadas.

No entanto, você deve usar esse atributo com muito cuidado. Se ele é implementado incorretamente, ele pode ter sérias implicações de segurança..

Para obter informações sobre como implementar os métodos, consulte o NativeMethods exemplo, SafeNativeMethods exemplo, e UnsafeNativeMethods exemplo.

Quando suprimir avisos

Não suprimir um aviso da regra.

Exemplo

O exemplo a seguir declara um método que viola essa regra. Para corrigir a violação, a RemoveDirectory P/Invoke deve ser movido para uma classe de apropriado é projetada para armazenar somente P/Invokes.

Imports System

NameSpace MSInternalLibrary

' Violates rule: MovePInvokesToNativeMethodsClass.
Friend Class UnmanagedApi
    Friend Declare Function RemoveDirectory Lib "kernel32" ( _
       ByVal Name As String) As Boolean
End Class

End NameSpace 
using System;
using System.Runtime.InteropServices;

namespace DesignLibrary
{
// Violates rule: MovePInvokesToNativeMethodsClass.
    internal class UnmanagedApi
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        internal static extern bool RemoveDirectory(string name);
    }
}

Exemplo de NativeMethods

Descrição

Porque o NativeMethods classe não deve ser marcada usando SuppressUnmanagedCodeSecurityAttribute, P/Invokes são colocados nele exigirá UnmanagedCode permissão. Porque a maioria dos aplicativos executados no computador local e executado com confiança total, isso geralmente não é um problema. No entanto, se você estiver desenvolvendo bibliotecas reutilizáveis, deverá considerar a definição um SafeNativeMethods ou UnsafeNativeMethods classe.

A exemplo a seguir mostra um Interaction.Beep método envolve o MessageBeep função em User32. dll. O MessageBeep P/Invoke é colocada na NativeMethods classe.

Código

Imports System    
Imports System.Runtime.InteropServices    
Imports System.ComponentModel         

Public NotInheritable Class Interaction  

    Private Sub New()        
    End Sub                

    ' Callers require Unmanaged permission        
    Public Shared Sub Beep()                        
        ' No need to demand a permission as callers of Interaction.Beep                     
        ' will require UnmanagedCode permission                     
        If Not NativeMethods.MessageBeep(-1) Then                
            Throw New Win32Exception()            
        End If

    End Sub  

End Class         

Friend NotInheritable Class NativeMethods  

    Private Sub New()        
    End Sub             

    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _        
    Friend Shared Function MessageBeep(ByVal uType As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean        
    End Function  

End Class
using System;    
using System.Runtime.InteropServices;    
using System.ComponentModel;              

public static class Interaction    
{        
    // Callers require Unmanaged permission        
    public static void Beep()           
    {            
        // No need to demand a permission as callers of Interaction.Beep            
        // will require UnmanagedCode permission            
        if (!NativeMethods.MessageBeep(-1))                
            throw new Win32Exception();        
    }    
}            

internal static class NativeMethods    
{        
    [DllImport("user32.dll", CharSet = CharSet.Auto)]        
    [return: MarshalAs(UnmanagedType.Bool)]        
    internal static extern bool MessageBeep(int uType);    
}

Exemplo de SafeNativeMethods

Descrição

Métodos de P/Invoke, que pode ser exposta com segurança para qualquer aplicativo e que não têm efeitos colaterais que devem ser colocados em uma classe chamada SafeNativeMethods. Você não tem permissões de demanda e você não tem muita atenção para onde eles são chamados.

A exemplo a seguir mostra um TickCount propriedade que envolve o ObterContagemMarcaEscala função a partir do Kernel32. dll.

Código

Imports System   
Imports System.Runtime.InteropServices   
Imports System.Security       

Public NotInheritable Class Environment       

    Private Sub New()       
    End Sub           

    ' Callers do not require Unmanaged permission       
    Public Shared ReadOnly Property TickCount() As Integer           
        Get               
            ' No need to demand a permission in place of               
            ' UnmanagedCode as GetTickCount is considered               
            ' a safe method               
            Return SafeNativeMethods.GetTickCount()               
        End Get       
    End Property       

End Class       

<SuppressUnmanagedCodeSecurityAttribute()> _   
Friend NotInheritable Class SafeNativeMethods             

    Private Sub New()       
    End Sub           

    <DllImport("kernel32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _       
    Friend Shared Function GetTickCount() As Integer       
    End Function       

End Class
using System;   
using System.Runtime.InteropServices;   
using System.Security;  

public static class Environment   
{       
    // Callers do not require UnmanagedCode permission       
    public static int TickCount        
    {           
        get           
        {              
            // No need to demand a permission in place of               
            // UnmanagedCode as GetTickCount is considered              
            // a safe method              
            return SafeNativeMethods.GetTickCount();           
        }       
    }   
}            

[SuppressUnmanagedCodeSecurityAttribute]   
internal static class SafeNativeMethods   
{       
    [DllImport("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]       
    internal static extern int GetTickCount();   
}

Exemplo de UnsafeNativeMethods

Descrição

Métodos de P/Invoke, que não pode ser chamado com segurança e que pode causar efeitos colaterais devem ser colocados em uma classe chamada UnsafeNativeMethods. Esses métodos devem ser verificados rigorosamente para certificar-se de que não estão expostos ao usuário involuntariamente. A regra CA2118: Revise o uso de SuppressUnmanagedCodeSecurityAttribute pode ajudar com isso. Como alternativa, os métodos devem ter outra permissão é exigida em vez de UnmanagedCode quando usá-los.

A exemplo a seguir mostra um Cursor.Hide método envolve o ShowCursor função em User32. dll.

Código

Imports System   
Imports System.Runtime.InteropServices   
Imports System.Security   
Imports System.Security.Permissions       

Public NotInheritable Class Cursor           

    Private Sub New()       
    End Sub           

    ' Callers do not require Unmanaged permission, however,         
    ' they do require UIPermission.AllWindows       
    Public Shared Sub Hide()                 
        ' Need to demand an appropriate permission                   
        ' in  place of UnmanagedCode permission as                    
        ' ShowCursor is not considered a safe method                   
        Dim permission As New UIPermission(UIPermissionWindow.AllWindows)           
        permission.Demand()           
        UnsafeNativeMethods.ShowCursor(False)                

    End Sub       

End Class       

<SuppressUnmanagedCodeSecurityAttribute()> _   
Friend NotInheritable Class UnsafeNativeMethods           

    Private Sub New()       
    End Sub           

    <DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _       
    Friend Shared Function ShowCursor(<MarshalAs(UnmanagedType.Bool)> ByVal bShow As Boolean) As Integer       
    End Function       

End Class
using System;   
using System.Runtime.InteropServices;   
using System.Security;   
using System.Security.Permissions;           

public static class Cursor   
{       
    // Callers do not require UnmanagedCode permission, however,       
    // they do require UIPermissionWindow.AllWindows       
    public static void Hide()          
    {           
        // Need to demand an appropriate permission           
        // in  place of UnmanagedCode permission as            
        // ShowCursor is not considered a safe method           
        new UIPermission(UIPermissionWindow.AllWindows).Demand();           
        UnsafeNativeMethods.ShowCursor(false);       
    }   
}            

[SuppressUnmanagedCodeSecurityAttribute]   
internal static class UnsafeNativeMethods   
{       
    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]       
    internal static extern int ShowCursor([MarshalAs(UnmanagedType.Bool)]bool bShow);   
}

Consulte também

Outros recursos

Avisos de design