Click to Rate and Give Feedback
MSDN
MSDN Library
.NET Development
Previous Versions
.NET Framework 3.0
Tools
Development Tools
FxCop
FxCop Warnings
Design Warnings
 Move pinvokes to native methods cla...
Collapse All/Expand All Collapse All
This page is specific to
Microsoft Visual Studio 2005/.NET Framework 2.0

Other versions are also available for the following:
Visual Studio Team System
Move pinvokes to native methods class

TypeName

MovePInvokesToNativeMethodsClass

CheckId

CA1060

Category

Microsoft.Design

Breaking Change

Breaking

A method uses Platform Invocation Services to access unmanaged code and is not a member of one of the 'NativeMethods' classes.

Platform Invocation methods, such as those marked with the System.Runtime.InteropServices.DllImportAttribute attribute, or methods defined by using the Declare keyword in Visual Basic, access unmanaged code. These methods should be in one of the following classes:

  • NativeMethods - This class does not suppress stack walks for unmanaged code permission. (System.Security.SuppressUnmanagedCodeSecurityAttribute must not be applied to this class.) This class is for methods that can be used anywhere because a stack walk will be performed.

  • SafeNativeMethods - This class suppresses stack walks for unmanaged code permission. (System.Security.SuppressUnmanagedCodeSecurityAttribute is applied to this class.) This class is for methods that are safe for anyone to call. Callers of these methods are not required to do a full security review to ensure that the usage is secure because the methods are harmless for any caller.

  • UnsafeNativeMethods - This class suppresses stack walks for unmanaged code permission. (System.Security.SuppressUnmanagedCodeSecurityAttribute is applied to this class.) This class is for methods that are potentially dangerous. Any caller of these methods must do a full security review to ensure that the usage is secure because no stack walk will be performed.

These classes are declared as internal (Friend, in Visual Basic), and declare a private constructor to prevent new instances from being created. The methods in these classes should be static and internal (Shared and Friend in Visual Basic).

To fix a violation of this rule, move the method to the appropriate NativeMethods class.

Do not exclude a warning from this rule.

The following example declares a method that violates this rule.

Visual Basic
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 
C#
using System;
using System.Runtime.InteropServices;

namespace DesignLibrary
{
// Violates rule: MovePInvokesToNativeMethodsClass.
    internal class UnmanagedApi
    {
        [DllImport("kernel32.dll")]
        internal static extern bool RemoveDirectory(string name);
    }
}
Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
How to Fix Violations      David M. Kean - MSFT   |   Edit   |   Show History

In the above example, the RemoveDirectory P/Invoke should be moved to an appropriate class that is designed to only hold P/Invokes.

For most applications, moving P/Invokes to a new class called NativeMethods is typically enough. However, in situations where you are developing reusable libraries for use in other applications then you should also consider defining two other classes called SafeNativeMethods and UnsafeNativeMethods . Both of these classes are similar to the NativeMethods class, however, they are marked with a special attribute called SuppressUnmanagedCodeSecurityAttribute . Applying this attribute causes the runtime to avoid performing a full stack walk to make sure that all callers have the UnmanagedCode permission when calling the p/invoke methods containing within these classes. The runtime will check your library for this permission at startup, however, not the assemblies that reference it. This can greatly improve performance when calling unmanaged code and also allows code with limited permissions to call these methods.

However, using this attribute should not be taken lightly, as implemented incorrectly it can actually have serious security implications.

For more information and examples on how to implement the NativeMethods, SafeNativeMethods and UnsafeNativeMethods classes, see the appropriate content blocks below.

Tags What's this?: Add a tag
Flag as ContentBug
NativeMethods Class      David M. Kean - MSFT   |   Edit   |   Show History

As the NativeMethods class should not be marked with SuppressUnmanagedCodeAttribute , P/Invokes placed within in it, will require UnmanagedCode permission. As most applications run from the local machine and run with FullTrust, this is usually not a problem. However, if you developing reusable libraries, you should instead consider defining a SafeNativeMethods or UnsafeNativeMethods class. For more information, see the appropriate content blocks below.

The following example shows a method Interaction.Beep that wraps the MessageBeep function from user32.dll, the MessageBeep p/invoke is placed within the NativeMethods class.

    [C#]

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

    
[Visual Basic]

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
     


In the example above, any assembly that calls NativeMethod.MessageBeep or Interaction.Beep will require UnmanagedCode permission.

Tags What's this?: Add a tag
Flag as ContentBug
SafeNativeMethods Class      David M. Kean - MSFT   |   Edit   |   Show History

P/Invoke methods that are safe to be exposed to any application and do not have any side effects should be placed in a class called SafeNativeMethods . No permissions need to be demanded and you do not need to pay too much attention to where they are getting called.

The following example shows a property Environment.TickCount that wraps the GetTickCount function from kernel32.dll.

   [C#]

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

   [Visual Basic]

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
    

In the above example, although the assembly that defines Environment.TickCount still requires UnmanagedCode permission, any callers of it do not.

Tags What's this?: Add a tag
Flag as ContentBug
UnsafeNativeMethods Class      David M. Kean - MSFT   |   Edit   |   Show History

P/Invoke methods that are not safe to be called by anyone and can cause side effects should be placed in a class called UnsafeNativeMethods . These methods should be either stringently checked to make sure that they are not being exposed to the user inadvertently (the rule Review SuppressUnmanagedCodeSecurity usage can help with this) or should have another permission demanded in place of UnmanagedCode when using them.

The following example shows a method Cursor.Hide that wraps the ShowCursor function from user32.dll.

   [C#]

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

   [Visual Basic]

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
    


In the above example, although the assembly that defines Cursor.Hide still requires UnmanagedCode permission, any callers of it do not. In place of UnmanagedCode however, callers will require UIPermission.AllWindows .

Tags What's this?: Add a tag
Flag as ContentBug
Processing
© 2009 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement | Site Feedback
Page view tracker