平台叫用安全性考量

Assert, Deny, 和 SecurityAction 列舉型別的 PermitOnly 成員,被稱為「堆疊查核行程」(Stack Walk) 修飾詞。 如果在平台叫用宣告及 COM 介面定義語言 (IDL) 陳述式上,這些成員被當成宣告屬性使用,就會忽略這些成員。

平台叫用範例

本節中的平台叫用範例,說明如何利用堆疊查核行程修飾詞,以使用 RegistryPermission 屬性。

下列程式範例中,SecurityAction Assert, Deny 和 PermitOnly 修飾詞會被忽略。

[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
[RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
    private static extern bool CallRegistryPermissionAssert();

[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
[RegistryPermission(SecurityAction.Deny, Unrestricted = true)]
    private static extern bool CallRegistryPermissionDeny();

[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
[RegistryPermission(SecurityAction.PermitOnly, Unrestricted = true)]
    private static extern bool CallRegistryPermissionDeny();

但是,下列範例就會接受 Demand 修飾詞。

[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
[RegistryPermission(SecurityAction.Demand, Unrestricted = true)]
    private static extern bool CallRegistryPermissionDeny();

如果 SecurityAction 修飾詞放在內含 (包裝) 平台叫用呼叫的類別中,就可以正確運作。

[RegistryPermission(SecurityAction.Demand, Unrestricted = true)]
public ref class PInvokeWrapper
{
public:
[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
    private static extern bool CallRegistryPermissionDeny();
};
[RegistryPermission(SecurityAction.Demand, Unrestricted = true)]
class PInvokeWrapper
{
[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
    private static extern bool CallRegistryPermissionDeny();
}

SecurityAction 修飾詞在巢狀案例中 (修飾詞放置在平台叫用呼叫的呼叫端上) 也可以正確運作:

{
public ref class PInvokeWrapper
public:
    [DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
    private static extern bool CallRegistryPermissionDeny();

    [RegistryPermission(SecurityAction.Demand, Unrestricted = true)]
    public static bool CallRegistryPermission()
    {
     return CallRegistryPermissionInternal();
    }
};
class PInvokeScenario
{
    [DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
    private static extern bool CallRegistryPermissionInternal();

    [RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
    public static bool CallRegistryPermission()
    {
     return CallRegistryPermissionInternal();
    }
}

COM Interop 範例

本節中的 COM Interop 範例,說明如何利用堆疊查核行程修飾詞,以使用 RegistryPermission 屬性。

下列 COM Interop 介面宣告會忽略 Assert、Deny 和 PermitOnly 修飾詞,類似上一節中的平台叫用範例。

[ComImport, Guid("12345678-43E6-43c9-9A13-47F40B338DE0")]
interface IAssertStubsItf
{
[RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
    bool CallRegistryPermission();
[FileIOPermission(SecurityAction.Assert, Unrestricted = true)]
    bool CallFileIoPermission();
}

[ComImport, Guid("12345678-43E6-43c9-9A13-47F40B338DE0")]
interface IDenyStubsItf
{
[RegistryPermission(SecurityAction.Deny, Unrestricted = true)]
    bool CallRegistryPermission();
[FileIOPermission(SecurityAction.Deny, Unrestricted = true)]
    bool CallFileIoPermission();
}

[ComImport, Guid("12345678-43E6-43c9-9A13-47F40B338DE0")]
interface IAssertStubsItf
{
[RegistryPermission(SecurityAction.PermitOnly, Unrestricted = true)]
    bool CallRegistryPermission();
[FileIOPermission(SecurityAction.PermitOnly, Unrestricted = true)]
    bool CallFileIoPermission();
}

此外,COM Interop 介面宣告案例中不接受 Demand 修飾詞,如以下範例所示。

[ComImport, Guid("12345678-43E6-43c9-9A13-47F40B338DE0")]
interface IDemandStubsItf
{
[RegistryPermission(SecurityAction.Demand, Unrestricted = true)]
    bool CallRegistryPermission();
[FileIOPermission(SecurityAction.Demand, Unrestricted = true)]
    bool CallFileIoPermission();
}

請參閱

參考

SecurityAction

概念

安全性權限

在 Managed 程式碼中建立原型

使用 Unmanaged DLL 函式

其他資源

與 Unmanaged 程式碼互通

互通性