Files
swyx/src/SwyxTray/NativeMethods.cs
T
Sven 78b17a1350 SwyxTray und Firefox-Plugin in das Repository aufnehmen
Windows-Tray-Anwendung (CLMgr-Anbindung an SwyxIt!) samt WebSocket-Zugang,
Firefox-Erweiterung und Browser-Beispielclient.
2026-08-21 11:33:52 +02:00

70 lines
2.9 KiB
C#

using System.Runtime.InteropServices;
namespace SwyxTray;
internal static class NativeMethods
{
/// <summary>
/// Gibt ein von <see cref="System.Drawing.Bitmap.GetHicon"/> erzeugtes
/// HICON frei. Ohne diesen Aufruf leckt jedes erzeugte Symbol ein
/// GDI-Handle.
///
/// Bewusst DllImport statt LibraryImport: Letzteres verlangt
/// AllowUnsafeBlocks fuer das gesamte Projekt, was fuer diesen einen
/// Aufruf unverhaeltnismaessig waere.
/// </summary>
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DestroyIcon(IntPtr hIcon);
private const uint RpcCAuthnLevelNone = 1;
private const uint RpcCImpLevelIdentify = 2;
private const uint EoacNone = 0;
/// <summary>Wurde zu spaet aufgerufen — COM war bereits gemarshallt.</summary>
private const int RpcETooLate = unchecked((int)0x80010119);
[DllImport("ole32.dll")]
private static extern int CoInitializeEx(IntPtr pvReserved, uint dwCoInit);
[DllImport("ole32.dll")]
private static extern int CoInitializeSecurity(
IntPtr pSecDesc, int cAuthSvc, IntPtr asAuthSvc, IntPtr pReserved1,
uint dwAuthnLevel, uint dwImpLevel, IntPtr pAuthList,
uint dwCapabilities, IntPtr pReserved3);
/// <summary>
/// Erlaubt CLMgr, Ereignisse in diesen Prozess zurueckzurufen.
///
/// CLMgr.exe ist ein eigener Prozess. Beim Anmelden der Ereignissenke
/// (<c>IConnectionPoint::Advise</c>) ruft CLMgr in unseren Prozess zurueck.
/// Ohne eigene Sicherheitsvorgabe verwendet COM Standardwerte, unter denen
/// dieser Rueckruf mit E_ACCESSDENIED abgewiesen wird.
///
/// Authentifizierungsstufe NONE bedeutet: eingehende COM-Aufrufe an diesen
/// Prozess werden nicht authentifiziert. Das ist die uebliche Einstellung
/// fuer COM-Ereignissenken und betrifft nur diesen Prozess, der ausser der
/// Senke keine Schnittstellen nach aussen anbietet. Wer es enger fassen
/// will, probiert RPC_C_AUTHN_LEVEL_CONNECT (2) — das genuegt, solange
/// CLMgr in derselben Sitzung und unter demselben Konto laeuft.
///
/// Muss vor dem ersten COM-Aufruf erfolgen; danach liefert Windows
/// RPC_E_TOO_LATE.
/// </summary>
/// <returns>HRESULT des Aufrufs, 0 = Erfolg.</returns>
internal static int InitializeComSecurity()
{
// Das Apartment steht durch [STAThread] fest; dieser Aufruf stellt nur
// sicher, dass COM initialisiert ist, bevor die Sicherheit gesetzt wird.
const uint coinitApartmentThreaded = 0x2;
CoInitializeEx(IntPtr.Zero, coinitApartmentThreaded);
return CoInitializeSecurity(
IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero,
RpcCAuthnLevelNone, RpcCImpLevelIdentify, IntPtr.Zero,
EoacNone, IntPtr.Zero);
}
internal static bool IsTooLate(int hresult) => hresult == RpcETooLate;
}