//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
// Security\SuppressSecurity.cs
using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;

class NativeMethods
{
    // Wywołanie do niezarządzanego kodu. Wykonanie tej metody wymaga
    // uprawnienia zabezpieczeń UnmanagedCode. Próba wywołania tej metody
    // bez takiego uprawnienia spowoduje zgłoszenie wyjatku SecurityException:
    /* UWAGA: Atrybut SuppressUnmanagedCodeSecurity wyłącza kontrolę
       uprawnienia UnmanagedCode w czasie pracy programu. Należy zachować ostrożność! */
    [SuppressUnmanagedCodeSecurity()]
    [DllImport("user32.dll")]
    internal static extern int MessageBox(uint hWnd, string lpText, 
       string lpCaption, uint uType);
}

class MainClass
{
    // Uprawnienie zabezpieczeń powiązane z tą metodą spowoduje usunięcie
    // uprawnienia UnmanagedCode z aktualnego zestawu uprawnień na czas
    // trwania wywołania tej metody:
    [SecurityPermission(SecurityAction.Deny, Flags = 
       SecurityPermissionFlag.UnmanagedCode)]
    private static void CallUnmanagedCodeWithoutPermission()
    {
        try
        {
            // Kontrola zabezpieczenia UnmanagedCode została wyłączona dla poniższego
            // wywołania. Niezarządzane wywołanie wyświetla jedynie interfejs użytkownika.
            // Bezpieczeństwo zostanie zachowane tylko wtedy, jeśli niezarządzane
            // wywołanie będzie posiadało uprawnienie UI:
            UIPermission uiPermission = 
               new UIPermission(PermissionState.Unrestricted);
            uiPermission.Demand();

            Console.WriteLine("Próba wywołania niezarządzanego kodu bez uprawnienia UnmanagedCode.");
            NativeMethods.MessageBox(0, "Witaj świecie!", "", 0);
            Console.WriteLine("Wywołano niezarządzany kod bez uprawnienia UnmanagedCode.");
        }
        catch (SecurityException)
        {
            Console.WriteLine("Przechwycono wyjątek zabezpieczeń w czasie próby wywołania niezarządzanego kodu.");
        }
    }

    // Uprawnienie zabezpieczeń powiązane z tą metodą spowoduje dodanie
    // uprawnienia UnmanagedCode do aktualnego zestawu uprawnień na czas
    // trwania wywołania tej metody:
    [SecurityPermission(SecurityAction.Assert, Flags = 
       SecurityPermissionFlag.UnmanagedCode)]
    private static void CallUnmanagedCodeWithPermission()
    {
        try
        {
            Console.WriteLine("Próba wywołania niezarządzanego kodu z uprawnieniem.");
            NativeMethods.MessageBox(0, "Witaj świecie!", "", 0);
            Console.WriteLine("Wywołano niezarządzany kod z uprawnieniem.");
        }
        catch (SecurityException)
        {
            Console.WriteLine("Przechwycono wyjątek zabezpieczeń w czasie próby wywołania niezarządzanego kodu.");
        }
    }

    public static void Main() 
    {
        CallUnmanagedCodeWithoutPermission();
        CallUnmanagedCodeWithPermission();
    }
}
