Windows-Tray-Anwendung (CLMgr-Anbindung an SwyxIt!) samt WebSocket-Zugang, Firefox-Erweiterung und Browser-Beispielclient.
70 lines
2.9 KiB
C#
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;
|
|
}
|