Skip to content

Instantly share code, notes, and snippets.

@macintoxic
Forked from akasubi/SecureDesktop.cs
Created April 13, 2021 04:17
Show Gist options
  • Select an option

  • Save macintoxic/47658b66db2e86c2e7e0817a2edd22cd to your computer and use it in GitHub Desktop.

Select an option

Save macintoxic/47658b66db2e86c2e7e0817a2edd22cd to your computer and use it in GitHub Desktop.

Revisions

  1. John Reynolds created this gist Feb 24, 2020.
    71 changes: 71 additions & 0 deletions SecureDesktop.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    using System;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;
    using System.Runtime.InteropServices;
    using System.Windows.Threading;

    class Program
    {
    // DESKTOP_ACCESS
    const UInt32 DESKTOP_NONE = 0x0000u;
    const UInt32 DESKTOP_READOBJECTS = 0x0001u;
    const UInt32 DESKTOP_CREATEWINDOW = 0x0002u;
    const UInt32 DESKTOP_CREATEMENU = 0x0004u;
    const UInt32 DESKTOP_HOOKCONTROL = 0x0008u;
    const UInt32 DESKTOP_JOURNALRECORD = 0x0010u;
    const UInt32 DESKTOP_JOURNALPLAYBACK = 0x0020u;
    const UInt32 DESKTOP_ENUMERATE = 0x0040u;
    const UInt32 DESKTOP_WRITEOBJECTS = 0x0080u;
    const UInt32 DESKTOP_SWITCHDESKTOP = 0x0100u;

    const UInt32 dwDesiredAccess =
    DESKTOP_READOBJECTS |
    DESKTOP_CREATEWINDOW |
    DESKTOP_CREATEMENU |
    DESKTOP_WRITEOBJECTS |
    DESKTOP_SWITCHDESKTOP;

    [DllImport("kernel32.dll")] static extern uint GetCurrentThreadId();
    [DllImport("user32.dll")] static extern IntPtr GetThreadDesktop(uint dwThreadId);
    [DllImport("user32.dll")] static extern IntPtr CreateDesktop(string desktopName, IntPtr device, IntPtr deviceMode, uint flags, uint accessMask, IntPtr attributes);
    [DllImport("user32.dll")] static extern bool SetThreadDesktop(IntPtr hDesktop);
    [DllImport("user32.dll")] static extern bool CloseDesktop(IntPtr hDesktop);
    [DllImport("user32.dll")] static extern bool SwitchDesktop(IntPtr hDesktop);

    [STAThread]
    public static void Main()
    {
    var btn = new Button() { Content = "Open secure desktop" };
    btn.Click += (s, e) => SecureDialog();
    var win = new Window() { Content = btn };
    new Application().Run(win);
    }

    static void SecureDialog()
    {
    var hOldDesktop = GetThreadDesktop(GetCurrentThreadId());
    var hNewDesktop = CreateDesktop("My desktop", IntPtr.Zero, IntPtr.Zero, 0, dwDesiredAccess, IntPtr.Zero);
    SwitchDesktop(hNewDesktop);

    var thread = new Thread( () => SecureDesktopThread(hNewDesktop) );
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join(); // Wait for thread to complete.

    SwitchDesktop(hOldDesktop);
    CloseDesktop(hNewDesktop);
    }

    static void SecureDesktopThread(IntPtr hNewDesktop)
    {
    SetThreadDesktop(hNewDesktop);

    SynchronizationContext.SetSynchronizationContext(
    new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));

    var win = new Window() { Content = "Hello World!", FontSize=30 };
    win.ShowDialog();
    Dispatcher.CurrentDispatcher.InvokeShutdown();
    }
    }