Window Stations & Desktops in .NET (2.)

V predchozim clanku jsem ukazal base tridu pro nase pojmenovane nativni objekty. Nyni si napiseme implementace SafeHandles, ktere budou predstavovat Win32 desktopy a window stations. Protoze MSDN dokumentace k funkcim OpenDesktop, CreateDesktop, a ostatnim, rika, ze navratova hodnota NULL znamena chybu, zdedime nase tridy z SafeHandleZeroOrMinusOneIsInvalid, abychom nemuseli implementovat vlastnost IsInvalid. Jedine co se od nas ceka, je defaultni konstruktor a metoda ReleaseHandle. Konstruktor musi predat base tride flag ownsHandle, ktery urcuje, zda ve finalizatoru dojde k zavolani metody ReleaseHandle, coz je presne to, co chceme.

public sealed class SafeWindowStationHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    public SafeWindowStationHandle()
        : base(true)
    {
    }

    protected override bool ReleaseHandle()
    {
        return SafeNativeMethods.CloseWindowStation(handle);
    }
}

public sealed class SafeDesktopHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    public SafeDesktopHandle()
        : base(true)
    {
    }

    protected override bool ReleaseHandle()
    {
        return SafeNativeMethods.CloseDesktop(handle);
    }
}

Jak vidite, tridy pouzivaji metody CloseDesktop a CloseWindowStation, ktere mam nadeklarovany ve tride SafeNativeMethods. Ta momentalne vypada takto:

[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
    [return: MarshalAs(UnmanagedType.Bool)]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
    [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern bool CloseWindowStation(IntPtr hWinsta);

    [return: MarshalAs(UnmanagedType.Bool)]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
    [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern bool CloseDesktop(IntPtr hDesktop);
}

Tady je potreba si vsimnout dvou veci: prvni je atribut SuppressUnmanagedCodeSecurity, ktery zamezi generovani bezpecnostnich kontrol JIT kompilatorem, ktere by mohly selhat v pripade nedostatku pameti nebo stack overflow. Nam staci, ze Code Access Security engine overi pravo volat nativni kod pri naloadovani nasi assembly, a pri kazdem volani uz si to muze odpustit.

Druhou veci jsou atributy ReliabilityContract na metodach. Ty popisuji jak se metody zachovaji v pripade vyjimecnych podminek typu nedostatku pameti nebo mista na stacku. Parametr Consistency rika, v jakem stavu zanecha metoda objekt, appdomenu nebo proces. My autorum Win32 duverujeme, a spolehneme se, ze tyto metody v nenadale situaci neponici vubec nic. Druhy parametr, Cer, rika, zda metoda udela co se od ni ceka. To s jistotou tvrdit nemuzeme, nicmene obe metody vraceji false v pripade ze selzou, tudiz pouzijeme hodnotu MayFail. Ta znamena, ze metoda muze selhat, ale alespon nam to da vedet, a runtime zaruci, ze se mu podari vratit navratovou hodnotu. Oproti tomu hodnota Success znamena, ze metoda uspeje i v pripade vyjimecne neprijemnych podminek. To by mohl by pripad treba funkce Kernel32!CloseHandle.

Priste si ukazeme, co s temito handles muzeme udelat.

Zveřejněno 18 června 07 03:45 by jachymko
Vedeno pod: , , ,

Komentář

Žádné komentáře
Neregistrovaní uživatele nemužou přidávat komentáře.
Vyvojar.cz na prodej!