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);
}