testing remote stuff
This commit is contained in:
parent
1e05d4576d
commit
3c9ccaafeb
374 changed files with 10526 additions and 2037 deletions
140
src/Remote/Insight.Remote.Shared/Native/Linux/LibX11.cs
Normal file
140
src/Remote/Insight.Remote.Shared/Native/Linux/LibX11.cs
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
|
||||
Copyright 1985, 1986, 1987, 1991, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Linux;
|
||||
|
||||
public static unsafe class LibX11
|
||||
{
|
||||
|
||||
[DllImport("libX11")]
|
||||
public static extern IntPtr XGetImage(IntPtr display, IntPtr drawable, int x, int y, int width, int height, long plane_mask, int format);
|
||||
|
||||
[DllImport("libX11")]
|
||||
public static extern IntPtr XDefaultVisual(IntPtr display, int screen_number);
|
||||
[DllImport("libX11")]
|
||||
public static extern int XScreenCount(IntPtr display);
|
||||
[DllImport("libX11")]
|
||||
public static extern int XDefaultScreen(IntPtr display);
|
||||
[DllImport("libX11")]
|
||||
public static extern IntPtr XOpenDisplay(string display_name);
|
||||
[DllImport("libX11")]
|
||||
public static extern void XCloseDisplay(IntPtr display);
|
||||
[DllImport("libX11")]
|
||||
public static extern IntPtr XRootWindow(IntPtr display, int screen_number);
|
||||
|
||||
[DllImport("libX11")]
|
||||
public static extern IntPtr XGetSubImage(IntPtr display, IntPtr drawable, int x, int y, uint width, uint height, ulong plane_mask, int format, IntPtr dest_image, int dest_x, int dest_y);
|
||||
[DllImport("libX11")]
|
||||
public static extern IntPtr XScreenOfDisplay(IntPtr display, int screen_number);
|
||||
[DllImport("libX11")]
|
||||
public static extern int XDisplayWidth(IntPtr display, int screen_number);
|
||||
[DllImport("libX11")]
|
||||
public static extern int XDisplayHeight(IntPtr display, int screen_number);
|
||||
[DllImport("libX11")]
|
||||
public static extern int XWidthOfScreen(IntPtr screen);
|
||||
[DllImport("libX11")]
|
||||
public static extern int XHeightOfScreen(IntPtr screen);
|
||||
[DllImport("libX11")]
|
||||
public static extern IntPtr XDefaultGC(IntPtr display, int screen_number);
|
||||
[DllImport("libX11")]
|
||||
public static extern IntPtr XDefaultRootWindow(IntPtr display);
|
||||
[DllImport("libX11")]
|
||||
public static extern void XGetInputFocus(IntPtr display, out IntPtr focus_return, out int revert_to_return);
|
||||
[DllImport("libX11")]
|
||||
public static extern IntPtr XStringToKeysym(string key);
|
||||
[DllImport("libX11")]
|
||||
public static extern uint XKeysymToKeycode(IntPtr display, IntPtr keysym);
|
||||
|
||||
[DllImport("libX11")]
|
||||
public static extern IntPtr XRootWindowOfScreen(IntPtr screen);
|
||||
[DllImport("libX11")]
|
||||
public static extern ulong XNextRequest(IntPtr display);
|
||||
[DllImport("libX11")]
|
||||
public static extern void XForceScreenSaver(IntPtr display, int mode);
|
||||
[DllImport("libX11")]
|
||||
public static extern void XSync(IntPtr display, bool discard);
|
||||
[DllImport("libX11")]
|
||||
public static extern void XDestroyImage(IntPtr ximage);
|
||||
|
||||
[DllImport("libX11")]
|
||||
public static extern void XNoOp(IntPtr display);
|
||||
|
||||
[DllImport("libX11")]
|
||||
public static extern void XFree(IntPtr data);
|
||||
|
||||
[DllImport("libX11")]
|
||||
public static extern int XGetWindowAttributes(IntPtr display, IntPtr window, out XWindowAttributes windowAttributes);
|
||||
|
||||
public struct XImage
|
||||
{
|
||||
public int width;
|
||||
public int height; /* size of image */
|
||||
public int xoffset; /* number of pixels offset in X direction */
|
||||
public int format; /* XYBitmap, XYPixmap, ZPixmap */
|
||||
//public char* data; /* pointer to image data */
|
||||
public IntPtr data; /* pointer to image data */
|
||||
public int byte_order; /* data byte order, LSBFirst, MSBFirst */
|
||||
public int bitmap_unit; /* quant. of scanline 8, 16, 32 */
|
||||
public int bitmap_bit_order; /* LSBFirst, MSBFirst */
|
||||
public int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */
|
||||
public int depth; /* depth of image */
|
||||
public int bytes_per_line; /* accelerator to next scanline */
|
||||
public int bits_per_pixel; /* bits per pixel (ZPixmap) */
|
||||
public ulong red_mask; /* bits in z arrangement */
|
||||
public ulong green_mask;
|
||||
public ulong blue_mask;
|
||||
public IntPtr obdata; /* hook for the object routines to hang on */
|
||||
}
|
||||
|
||||
public struct XWindowAttributes
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
public int width;
|
||||
public int height;
|
||||
public int border_width;
|
||||
public int depth;
|
||||
public IntPtr visual;
|
||||
public IntPtr root;
|
||||
public int @class;
|
||||
public int bit_gravity;
|
||||
public int win_gravity;
|
||||
public int backing_store;
|
||||
public ulong backing_planes;
|
||||
public ulong backing_pixel;
|
||||
public bool save_under;
|
||||
public IntPtr colormap;
|
||||
public bool map_installed;
|
||||
public int map_state;
|
||||
public long all_event_masks;
|
||||
public long your_event_mask;
|
||||
public long do_not_propagate_mask;
|
||||
public bool override_redirect;
|
||||
public IntPtr screen;
|
||||
}
|
||||
}
|
||||
15
src/Remote/Insight.Remote.Shared/Native/Linux/LibXtst.cs
Normal file
15
src/Remote/Insight.Remote.Shared/Native/Linux/LibXtst.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Linux;
|
||||
|
||||
public class LibXtst
|
||||
{
|
||||
[DllImport("libXtst")]
|
||||
public static extern bool XTestQueryExtension(IntPtr display, out int event_base, out int error_base, out int major_version, out int minor_version);
|
||||
[DllImport("libXtst")]
|
||||
public static extern void XTestFakeKeyEvent(IntPtr display, uint keycode, bool is_press, ulong delay);
|
||||
[DllImport("libXtst")]
|
||||
public static extern void XTestFakeButtonEvent(IntPtr display, uint button, bool is_press, ulong delay);
|
||||
[DllImport("libXtst")]
|
||||
public static extern void XTestFakeMotionEvent(IntPtr display, int screen_number, int x, int y, ulong delay);
|
||||
}
|
||||
9
src/Remote/Insight.Remote.Shared/Native/Linux/Libc.cs
Normal file
9
src/Remote/Insight.Remote.Shared/Native/Linux/Libc.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Linux;
|
||||
|
||||
public class Libc
|
||||
{
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
public static extern uint geteuid();
|
||||
}
|
||||
62
src/Remote/Insight.Remote.Shared/Native/Linux/libXrandr.cs
Normal file
62
src/Remote/Insight.Remote.Shared/Native/Linux/libXrandr.cs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright © 2000 Compaq Computer Corporation, Inc.
|
||||
* Copyright © 2002 Hewlett-Packard Company, Inc.
|
||||
* Copyright © 2006 Intel Corporation
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
|
||||
* Keith Packard, Intel Corporation
|
||||
*/
|
||||
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Linux;
|
||||
|
||||
public static class LibXrandr
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XRRMonitorInfo
|
||||
{
|
||||
// Atom
|
||||
public IntPtr name;
|
||||
public bool primary;
|
||||
public bool automatic;
|
||||
public int noutput;
|
||||
public int x;
|
||||
public int y;
|
||||
public int width;
|
||||
public int height;
|
||||
public int mwidth;
|
||||
public int mheight;
|
||||
// RROutput*
|
||||
public IntPtr outputs;
|
||||
}
|
||||
|
||||
[DllImport("libXrandr")]
|
||||
public static extern IntPtr XRRGetMonitors(IntPtr display, IntPtr window, bool get_active, out int monitors);
|
||||
|
||||
[DllImport("libXrandr")]
|
||||
public static extern void XRRFreeMonitors(IntPtr monitors);
|
||||
|
||||
[DllImport("libXrandr")]
|
||||
public static extern IntPtr XRRAllocateMonitor(IntPtr display, int output);
|
||||
}
|
||||
364
src/Remote/Insight.Remote.Shared/Native/Windows/ADVAPI32.cs
Normal file
364
src/Remote/Insight.Remote.Shared/Native/Windows/ADVAPI32.cs
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Windows;
|
||||
|
||||
public static class ADVAPI32
|
||||
{
|
||||
#region Structs
|
||||
public struct TOKEN_PRIVILEGES
|
||||
{
|
||||
public struct LUID
|
||||
{
|
||||
public uint LowPart;
|
||||
public int HighPart;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct LUID_AND_ATTRIBUTES
|
||||
{
|
||||
public LUID Luid;
|
||||
public uint Attributes;
|
||||
}
|
||||
public int PrivilegeCount;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ANYSIZE_ARRAY)]
|
||||
public LUID_AND_ATTRIBUTES[] Privileges;
|
||||
}
|
||||
public class USEROBJECTFLAGS
|
||||
{
|
||||
public int fInherit = 0;
|
||||
public int fReserved = 0;
|
||||
public int dwFlags = 0;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
public int Length;
|
||||
public IntPtr lpSecurityDescriptor;
|
||||
public bool bInheritHandle;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PROCESS_INFORMATION
|
||||
{
|
||||
public IntPtr hProcess;
|
||||
public IntPtr hThread;
|
||||
public int dwProcessId;
|
||||
public int dwThreadId;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct STARTUPINFO
|
||||
{
|
||||
public int cb;
|
||||
public string lpReserved;
|
||||
public string lpDesktop;
|
||||
public string lpTitle;
|
||||
public int dwX;
|
||||
public int dwY;
|
||||
public int dwXSize;
|
||||
public int dwYSize;
|
||||
public int dwXCountChars;
|
||||
public int dwYCountChars;
|
||||
public int dwFillAttribute;
|
||||
public int dwFlags;
|
||||
public short wShowWindow;
|
||||
public short cbReserved2;
|
||||
public IntPtr lpReserved2;
|
||||
public IntPtr hStdInput;
|
||||
public IntPtr hStdOutput;
|
||||
public IntPtr hStdError;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Enums
|
||||
public enum TOKEN_INFORMATION_CLASS
|
||||
{
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_USER structure that contains the user account of the token.
|
||||
/// </summary>
|
||||
TokenUser = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_GROUPS structure that contains the group accounts associated with the token.
|
||||
/// </summary>
|
||||
TokenGroups,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_PRIVILEGES structure that contains the privileges of the token.
|
||||
/// </summary>
|
||||
TokenPrivileges,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_OWNER structure that contains the default owner security identifier (SID) for newly created objects.
|
||||
/// </summary>
|
||||
TokenOwner,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_PRIMARY_GROUP structure that contains the default primary group SID for newly created objects.
|
||||
/// </summary>
|
||||
TokenPrimaryGroup,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_DEFAULT_DACL structure that contains the default DACL for newly created objects.
|
||||
/// </summary>
|
||||
TokenDefaultDacl,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_SOURCE structure that contains the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information.
|
||||
/// </summary>
|
||||
TokenSource,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_TYPE value that indicates whether the token is a primary or impersonation token.
|
||||
/// </summary>
|
||||
TokenType,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a SECURITY_IMPERSONATION_LEVEL value that indicates the impersonation level of the token. If the access token is not an impersonation token, the function fails.
|
||||
/// </summary>
|
||||
TokenImpersonationLevel,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_STATISTICS structure that contains various token statistics.
|
||||
/// </summary>
|
||||
TokenStatistics,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_GROUPS structure that contains the list of restricting SIDs in a restricted token.
|
||||
/// </summary>
|
||||
TokenRestrictedSids,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that indicates the Terminal Services session identifier that is associated with the token.
|
||||
/// </summary>
|
||||
TokenSessionId,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_GROUPS_AND_PRIVILEGES structure that contains the user SID, the group accounts, the restricted SIDs, and the authentication ID associated with the token.
|
||||
/// </summary>
|
||||
TokenGroupsAndPrivileges,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved.
|
||||
/// </summary>
|
||||
TokenSessionReference,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that is nonzero if the token includes the SANDBOX_INERT flag.
|
||||
/// </summary>
|
||||
TokenSandBoxInert,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved.
|
||||
/// </summary>
|
||||
TokenAuditPolicy,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_ORIGIN value.
|
||||
/// </summary>
|
||||
TokenOrigin,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_ELEVATION_TYPE value that specifies the elevation level of the token.
|
||||
/// </summary>
|
||||
TokenElevationType,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_LINKED_TOKEN structure that contains a handle to another token that is linked to this token.
|
||||
/// </summary>
|
||||
TokenLinkedToken,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_ELEVATION structure that specifies whether the token is elevated.
|
||||
/// </summary>
|
||||
TokenElevation,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that is nonzero if the token has ever been filtered.
|
||||
/// </summary>
|
||||
TokenHasRestrictions,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_ACCESS_INFORMATION structure that specifies security information contained in the token.
|
||||
/// </summary>
|
||||
TokenAccessInformation,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that is nonzero if virtualization is allowed for the token.
|
||||
/// </summary>
|
||||
TokenVirtualizationAllowed,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that is nonzero if virtualization is enabled for the token.
|
||||
/// </summary>
|
||||
TokenVirtualizationEnabled,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_MANDATORY_LABEL structure that specifies the token's integrity level.
|
||||
/// </summary>
|
||||
TokenIntegrityLevel,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that is nonzero if the token has the UIAccess flag set.
|
||||
/// </summary>
|
||||
TokenUIAccess,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_MANDATORY_POLICY structure that specifies the token's mandatory integrity policy.
|
||||
/// </summary>
|
||||
TokenMandatoryPolicy,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives the token's logon security identifier (SID).
|
||||
/// </summary>
|
||||
TokenLogonSid,
|
||||
|
||||
/// <summary>
|
||||
/// The maximum value for this enumeration
|
||||
/// </summary>
|
||||
MaxTokenInfoClass
|
||||
}
|
||||
public enum LOGON_TYPE
|
||||
{
|
||||
LOGON32_LOGON_INTERACTIVE = 2,
|
||||
LOGON32_LOGON_NETWORK,
|
||||
LOGON32_LOGON_BATCH,
|
||||
LOGON32_LOGON_SERVICE,
|
||||
LOGON32_LOGON_UNLOCK = 7,
|
||||
LOGON32_LOGON_NETWORK_CLEARTEXT,
|
||||
LOGON32_LOGON_NEW_CREDENTIALS
|
||||
}
|
||||
public enum LOGON_PROVIDER
|
||||
{
|
||||
LOGON32_PROVIDER_DEFAULT,
|
||||
LOGON32_PROVIDER_WINNT35,
|
||||
LOGON32_PROVIDER_WINNT40,
|
||||
LOGON32_PROVIDER_WINNT50
|
||||
}
|
||||
[Flags]
|
||||
public enum CreateProcessFlags
|
||||
{
|
||||
CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
|
||||
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
|
||||
CREATE_NEW_CONSOLE = 0x00000010,
|
||||
CREATE_NEW_PROCESS_GROUP = 0x00000200,
|
||||
CREATE_NO_WINDOW = 0x08000000,
|
||||
CREATE_PROTECTED_PROCESS = 0x00040000,
|
||||
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
|
||||
CREATE_SEPARATE_WOW_VDM = 0x00000800,
|
||||
CREATE_SHARED_WOW_VDM = 0x00001000,
|
||||
CREATE_SUSPENDED = 0x00000004,
|
||||
CREATE_UNICODE_ENVIRONMENT = 0x00000400,
|
||||
DEBUG_ONLY_THIS_PROCESS = 0x00000002,
|
||||
DEBUG_PROCESS = 0x00000001,
|
||||
DETACHED_PROCESS = 0x00000008,
|
||||
EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
|
||||
INHERIT_PARENT_AFFINITY = 0x00010000
|
||||
}
|
||||
public enum TOKEN_TYPE : int
|
||||
{
|
||||
TokenPrimary = 1,
|
||||
TokenImpersonation = 2
|
||||
}
|
||||
|
||||
public enum SECURITY_IMPERSONATION_LEVEL : int
|
||||
{
|
||||
SecurityAnonymous = 0,
|
||||
SecurityIdentification = 1,
|
||||
SecurityImpersonation = 2,
|
||||
SecurityDelegation = 3,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constants
|
||||
public const int TOKEN_DUPLICATE = 0x0002;
|
||||
public const uint MAXIMUM_ALLOWED = 0x2000000;
|
||||
public const int CREATE_NEW_CONSOLE = 0x00000010;
|
||||
public const int CREATE_NO_WINDOW = 0x08000000;
|
||||
public const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
|
||||
public const int STARTF_USESHOWWINDOW = 0x00000001;
|
||||
public const int DETACHED_PROCESS = 0x00000008;
|
||||
public const int TOKEN_ALL_ACCESS = 0x000f01ff;
|
||||
public const int PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF;
|
||||
public const int STANDARD_RIGHTS_REQUIRED = 0x000F0000;
|
||||
public const int SYNCHRONIZE = 0x00100000;
|
||||
|
||||
public const int IDLE_PRIORITY_CLASS = 0x40;
|
||||
public const int NORMAL_PRIORITY_CLASS = 0x20;
|
||||
public const int HIGH_PRIORITY_CLASS = 0x80;
|
||||
public const int REALTIME_PRIORITY_CLASS = 0x100;
|
||||
public const uint SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001;
|
||||
public const uint SE_PRIVILEGE_ENABLED = 0x00000002;
|
||||
public const uint SE_PRIVILEGE_REMOVED = 0x00000004;
|
||||
public const uint SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000;
|
||||
public const int ANYSIZE_ARRAY = 1;
|
||||
|
||||
public const int UOI_FLAGS = 1;
|
||||
public const int UOI_NAME = 2;
|
||||
public const int UOI_TYPE = 3;
|
||||
public const int UOI_USER_SID = 4;
|
||||
public const int UOI_HEAPSIZE = 5;
|
||||
public const int UOI_IO = 6;
|
||||
#endregion
|
||||
|
||||
#region DLL Imports
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool AdjustTokenPrivileges(IntPtr tokenHandle,
|
||||
[MarshalAs(UnmanagedType.Bool)] bool disableAllPrivileges,
|
||||
ref TOKEN_PRIVILEGES newState,
|
||||
uint bufferLengthInBytes,
|
||||
ref TOKEN_PRIVILEGES previousState,
|
||||
out uint returnLengthInBytes);
|
||||
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
public static extern bool CreateProcessAsUser(
|
||||
IntPtr hToken,
|
||||
string? lpApplicationName,
|
||||
string lpCommandLine,
|
||||
ref SECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
ref SECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
bool bInheritHandles,
|
||||
uint dwCreationFlags,
|
||||
IntPtr lpEnvironment,
|
||||
string? lpCurrentDirectory,
|
||||
ref STARTUPINFO lpStartupInfo,
|
||||
out PROCESS_INFORMATION lpProcessInformation);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool AllocateLocallyUniqueId(out IntPtr pLuid);
|
||||
|
||||
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||
public static extern SECUR32.WinErrors LsaNtStatusToWinError(SECUR32.WinStatusCodes status);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool GetTokenInformation(
|
||||
IntPtr TokenHandle,
|
||||
SECUR32.TOKEN_INFORMATION_CLASS TokenInformationClass,
|
||||
IntPtr TokenInformation,
|
||||
uint TokenInformationLength,
|
||||
out uint ReturnLength);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool LogonUser(
|
||||
[MarshalAs(UnmanagedType.LPStr)] string pszUserName,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string pszDomain,
|
||||
[MarshalAs(UnmanagedType.LPStr)] string pszPassword,
|
||||
int dwLogonType,
|
||||
int dwLogonProvider,
|
||||
out IntPtr phToken);
|
||||
|
||||
[DllImport("advapi32", SetLastError = true), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, ref IntPtr TokenHandle);
|
||||
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern bool DuplicateTokenEx(
|
||||
IntPtr hExistingToken,
|
||||
uint dwDesiredAccess,
|
||||
ref SECURITY_ATTRIBUTES lpTokenAttributes,
|
||||
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
|
||||
TOKEN_TYPE TokenType,
|
||||
out IntPtr phNewToken);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = false)]
|
||||
public static extern uint LsaNtStatusToWinError(uint status);
|
||||
#endregion
|
||||
}
|
||||
79
src/Remote/Insight.Remote.Shared/Native/Windows/GDI32.cs
Normal file
79
src/Remote/Insight.Remote.Shared/Native/Windows/GDI32.cs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Windows;
|
||||
|
||||
public static class GDI32
|
||||
{
|
||||
#region Enums
|
||||
/// <summary>
|
||||
/// Specifies a raster-operation code. These codes define how the color data for the
|
||||
/// source rectangle is to be combined with the color data for the destination
|
||||
/// rectangle to achieve the final color.
|
||||
/// </summary>
|
||||
public enum TernaryRasterOperations : uint
|
||||
{
|
||||
/// <summary>dest = source</summary>
|
||||
SRCCOPY = 0x00CC0020,
|
||||
/// <summary>dest = source OR dest</summary>
|
||||
SRCPAINT = 0x00EE0086,
|
||||
/// <summary>dest = source AND dest</summary>
|
||||
SRCAND = 0x008800C6,
|
||||
/// <summary>dest = source XOR dest</summary>
|
||||
SRCINVERT = 0x00660046,
|
||||
/// <summary>dest = source AND (NOT dest)</summary>
|
||||
SRCERASE = 0x00440328,
|
||||
/// <summary>dest = (NOT source)</summary>
|
||||
NOTSRCCOPY = 0x00330008,
|
||||
/// <summary>dest = (NOT src) AND (NOT dest)</summary>
|
||||
NOTSRCERASE = 0x001100A6,
|
||||
/// <summary>dest = (source AND pattern)</summary>
|
||||
MERGECOPY = 0x00C000CA,
|
||||
/// <summary>dest = (NOT source) OR dest</summary>
|
||||
MERGEPAINT = 0x00BB0226,
|
||||
/// <summary>dest = pattern</summary>
|
||||
PATCOPY = 0x00F00021,
|
||||
/// <summary>dest = DPSnoo</summary>
|
||||
PATPAINT = 0x00FB0A09,
|
||||
/// <summary>dest = pattern XOR dest</summary>
|
||||
PATINVERT = 0x005A0049,
|
||||
/// <summary>dest = (NOT dest)</summary>
|
||||
DSTINVERT = 0x00550009,
|
||||
/// <summary>dest = BLACK</summary>
|
||||
BLACKNESS = 0x00000042,
|
||||
/// <summary>dest = WHITE</summary>
|
||||
WHITENESS = 0x00FF0062,
|
||||
/// <summary>
|
||||
/// Capture window as seen on screen. This includes layered windows
|
||||
/// such as WPF windows with AllowsTransparency="true"
|
||||
/// </summary>
|
||||
CAPTUREBLT = 0x40000000
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DLL Imports
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
public static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData);
|
||||
|
||||
[DllImport("GDI32.dll")]
|
||||
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); [DllImport("GDI32.dll")]
|
||||
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
|
||||
|
||||
[DllImport("GDI32.dll")]
|
||||
public static extern bool DeleteDC(IntPtr hdc);
|
||||
|
||||
[DllImport("GDI32.dll")]
|
||||
public static extern bool DeleteObject(IntPtr hObject);
|
||||
|
||||
[DllImport("GDI32.dll")]
|
||||
public static extern IntPtr GetDeviceCaps(IntPtr hdc, int nIndex);
|
||||
|
||||
[DllImport("GDI32.dll")]
|
||||
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
|
||||
|
||||
#endregion
|
||||
}
|
||||
88
src/Remote/Insight.Remote.Shared/Native/Windows/Kernel32.cs
Normal file
88
src/Remote/Insight.Remote.Shared/Native/Windows/Kernel32.cs
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Windows;
|
||||
|
||||
public static class Kernel32
|
||||
{
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool CloseHandle(IntPtr hSnapshot);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr GetCommandLine();
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr GetConsoleWindow();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool ProcessIdToSessionId(uint dwProcessId, ref uint pSessionId);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint WTSGetActiveConsoleSessionId();
|
||||
|
||||
/// <summary>
|
||||
/// contains information about the current state of both physical and virtual memory, including extended memory
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public class MEMORYSTATUSEX
|
||||
{
|
||||
/// <summary>
|
||||
/// Size of the structure, in bytes. You must set this member before calling GlobalMemoryStatusEx.
|
||||
/// </summary>
|
||||
public uint dwLength;
|
||||
|
||||
/// <summary>
|
||||
/// Number between 0 and 100 that specifies the approximate percentage of physical memory that is in use (0 indicates no memory use and 100 indicates full memory use).
|
||||
/// </summary>
|
||||
public uint dwMemoryLoad;
|
||||
|
||||
/// <summary>
|
||||
/// Total size of physical memory, in bytes.
|
||||
/// </summary>
|
||||
public ulong ullTotalPhys;
|
||||
|
||||
/// <summary>
|
||||
/// Size of physical memory available, in bytes.
|
||||
/// </summary>
|
||||
public ulong ullAvailPhys;
|
||||
|
||||
/// <summary>
|
||||
/// Size of the committed memory limit, in bytes. This is physical memory plus the size of the page file, minus a small overhead.
|
||||
/// </summary>
|
||||
public ulong ullTotalPageFile;
|
||||
|
||||
/// <summary>
|
||||
/// Size of available memory to commit, in bytes. The limit is ullTotalPageFile.
|
||||
/// </summary>
|
||||
public ulong ullAvailPageFile;
|
||||
|
||||
/// <summary>
|
||||
/// Total size of the user mode portion of the virtual address space of the calling process, in bytes.
|
||||
/// </summary>
|
||||
public ulong ullTotalVirtual;
|
||||
|
||||
/// <summary>
|
||||
/// Size of unreserved and uncommitted memory in the user mode portion of the virtual address space of the calling process, in bytes.
|
||||
/// </summary>
|
||||
public ulong ullAvailVirtual;
|
||||
|
||||
/// <summary>
|
||||
/// Size of unreserved and uncommitted memory in the extended portion of the virtual address space of the calling process, in bytes.
|
||||
/// </summary>
|
||||
public ulong ullAvailExtendedVirtual;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:MEMORYSTATUSEX"/> class.
|
||||
/// </summary>
|
||||
public MEMORYSTATUSEX()
|
||||
{
|
||||
dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));
|
||||
}
|
||||
}
|
||||
}
|
||||
376
src/Remote/Insight.Remote.Shared/Native/Windows/SECUR32.cs
Normal file
376
src/Remote/Insight.Remote.Shared/Native/Windows/SECUR32.cs
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
using Microsoft.Win32.SafeHandles;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Windows;
|
||||
|
||||
public static class SECUR32
|
||||
{
|
||||
public enum WinStatusCodes : uint
|
||||
{
|
||||
STATUS_SUCCESS = 0
|
||||
}
|
||||
|
||||
public enum WinErrors : uint
|
||||
{
|
||||
NO_ERROR = 0,
|
||||
}
|
||||
public enum WinLogonType
|
||||
{
|
||||
LOGON32_LOGON_INTERACTIVE = 2,
|
||||
LOGON32_LOGON_NETWORK = 3,
|
||||
LOGON32_LOGON_BATCH = 4,
|
||||
LOGON32_LOGON_SERVICE = 5,
|
||||
LOGON32_LOGON_UNLOCK = 7,
|
||||
LOGON32_LOGON_NETWORK_CLEARTEXT = 8,
|
||||
LOGON32_LOGON_NEW_CREDENTIALS = 9
|
||||
}
|
||||
|
||||
// SECURITY_LOGON_TYPE
|
||||
public enum SecurityLogonType
|
||||
{
|
||||
Interactive = 2, // Interactively logged on (locally or remotely)
|
||||
Network, // Accessing system via network
|
||||
Batch, // Started via a batch queue
|
||||
Service, // Service started by service controller
|
||||
Proxy, // Proxy logon
|
||||
Unlock, // Unlock workstation
|
||||
NetworkCleartext, // Network logon with cleartext credentials
|
||||
NewCredentials, // Clone caller, new default credentials
|
||||
RemoteInteractive, // Remote, yet interactive. Terminal server
|
||||
CachedInteractive, // Try cached credentials without hitting the net.
|
||||
CachedRemoteInteractive, // Same as RemoteInteractive, this is used internally for auditing purpose
|
||||
CachedUnlock // Cached Unlock workstation
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LSA_UNICODE_STRING
|
||||
{
|
||||
public UInt16 Length;
|
||||
public UInt16 MaximumLength;
|
||||
public IntPtr Buffer;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TOKEN_SOURCE
|
||||
{
|
||||
public TOKEN_SOURCE(string name)
|
||||
{
|
||||
SourceName = new byte[8];
|
||||
System.Text.Encoding.GetEncoding(1252).GetBytes(name, 0, name.Length, SourceName, 0);
|
||||
if (!ADVAPI32.AllocateLocallyUniqueId(out SourceIdentifier))
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
}
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] SourceName;
|
||||
public IntPtr SourceIdentifier;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KERB_INTERACTIVE_LOGON
|
||||
{
|
||||
public KERB_LOGON_SUBMIT_TYPE MessageType;
|
||||
public string LogonDomainName;
|
||||
public string UserName;
|
||||
public string Password;
|
||||
}
|
||||
public enum KERB_LOGON_SUBMIT_TYPE
|
||||
{
|
||||
KerbInteractiveLogon = 2,
|
||||
KerbSmartCardLogon = 6,
|
||||
KerbWorkstationUnlockLogon = 7,
|
||||
KerbSmartCardUnlockLogon = 8,
|
||||
KerbProxyLogon = 9,
|
||||
KerbTicketLogon = 10,
|
||||
KerbTicketUnlockLogon = 11,
|
||||
KerbS4ULogon = 12,
|
||||
KerbCertificateLogon = 13,
|
||||
KerbCertificateS4ULogon = 14,
|
||||
KerbCertificateUnlockLogon = 15
|
||||
}
|
||||
public enum TOKEN_INFORMATION_CLASS
|
||||
{
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_USER structure that contains the user account of the token.
|
||||
/// </summary>
|
||||
TokenUser = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_GROUPS structure that contains the group accounts associated with the token.
|
||||
/// </summary>
|
||||
TokenGroups,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_PRIVILEGES structure that contains the privileges of the token.
|
||||
/// </summary>
|
||||
TokenPrivileges,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_OWNER structure that contains the default owner security identifier (SID) for newly created objects.
|
||||
/// </summary>
|
||||
TokenOwner,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_PRIMARY_GROUP structure that contains the default primary group SID for newly created objects.
|
||||
/// </summary>
|
||||
TokenPrimaryGroup,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_DEFAULT_DACL structure that contains the default DACL for newly created objects.
|
||||
/// </summary>
|
||||
TokenDefaultDacl,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_SOURCE structure that contains the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information.
|
||||
/// </summary>
|
||||
TokenSource,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_TYPE value that indicates whether the token is a primary or impersonation token.
|
||||
/// </summary>
|
||||
TokenType,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a SECURITY_IMPERSONATION_LEVEL value that indicates the impersonation level of the token. If the access token is not an impersonation token, the function fails.
|
||||
/// </summary>
|
||||
TokenImpersonationLevel,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_STATISTICS structure that contains various token statistics.
|
||||
/// </summary>
|
||||
TokenStatistics,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_GROUPS structure that contains the list of restricting SIDs in a restricted token.
|
||||
/// </summary>
|
||||
TokenRestrictedSids,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that indicates the Terminal Services session identifier that is associated with the token.
|
||||
/// </summary>
|
||||
TokenSessionId,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_GROUPS_AND_PRIVILEGES structure that contains the user SID, the group accounts, the restricted SIDs, and the authentication ID associated with the token.
|
||||
/// </summary>
|
||||
TokenGroupsAndPrivileges,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved.
|
||||
/// </summary>
|
||||
TokenSessionReference,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that is nonzero if the token includes the SANDBOX_INERT flag.
|
||||
/// </summary>
|
||||
TokenSandBoxInert,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved.
|
||||
/// </summary>
|
||||
TokenAuditPolicy,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_ORIGIN value.
|
||||
/// </summary>
|
||||
TokenOrigin,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_ELEVATION_TYPE value that specifies the elevation level of the token.
|
||||
/// </summary>
|
||||
TokenElevationType,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_LINKED_TOKEN structure that contains a handle to another token that is linked to this token.
|
||||
/// </summary>
|
||||
TokenLinkedToken,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_ELEVATION structure that specifies whether the token is elevated.
|
||||
/// </summary>
|
||||
TokenElevation,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that is nonzero if the token has ever been filtered.
|
||||
/// </summary>
|
||||
TokenHasRestrictions,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_ACCESS_INFORMATION structure that specifies security information contained in the token.
|
||||
/// </summary>
|
||||
TokenAccessInformation,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that is nonzero if virtualization is allowed for the token.
|
||||
/// </summary>
|
||||
TokenVirtualizationAllowed,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that is nonzero if virtualization is enabled for the token.
|
||||
/// </summary>
|
||||
TokenVirtualizationEnabled,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_MANDATORY_LABEL structure that specifies the token's integrity level.
|
||||
/// </summary>
|
||||
TokenIntegrityLevel,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a DWORD value that is nonzero if the token has the UIAccess flag set.
|
||||
/// </summary>
|
||||
TokenUIAccess,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives a TOKEN_MANDATORY_POLICY structure that specifies the token's mandatory integrity policy.
|
||||
/// </summary>
|
||||
TokenMandatoryPolicy,
|
||||
|
||||
/// <summary>
|
||||
/// The buffer receives the token's logon security identifier (SID).
|
||||
/// </summary>
|
||||
TokenLogonSid,
|
||||
|
||||
/// <summary>
|
||||
/// The maximum value for this enumeration
|
||||
/// </summary>
|
||||
MaxTokenInfoClass
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct QUOTA_LIMITS
|
||||
{
|
||||
readonly UInt32 PagedPoolLimit;
|
||||
readonly UInt32 NonPagedPoolLimit;
|
||||
readonly UInt32 MinimumWorkingSetSize;
|
||||
readonly UInt32 MaximumWorkingSetSize;
|
||||
readonly UInt32 PagefileLimit;
|
||||
readonly Int64 TimeLimit;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LSA_STRING
|
||||
{
|
||||
public UInt16 Length;
|
||||
public UInt16 MaximumLength;
|
||||
public /*PCHAR*/ IntPtr Buffer;
|
||||
}
|
||||
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = true)]
|
||||
public static extern WinStatusCodes LsaLogonUser(
|
||||
[In] IntPtr LsaHandle,
|
||||
[In] ref LSA_STRING OriginName,
|
||||
[In] SecurityLogonType LogonType,
|
||||
[In] UInt32 AuthenticationPackage,
|
||||
[In] IntPtr AuthenticationInformation,
|
||||
[In] UInt32 AuthenticationInformationLength,
|
||||
[In] /*PTOKEN_GROUPS*/ IntPtr LocalGroups,
|
||||
[In] ref TOKEN_SOURCE SourceContext,
|
||||
[Out] /*PVOID*/ out IntPtr ProfileBuffer,
|
||||
[Out] out UInt32 ProfileBufferLength,
|
||||
[Out] out Int64 LogonId,
|
||||
[Out] out IntPtr Token,
|
||||
[Out] out QUOTA_LIMITS Quotas,
|
||||
[Out] out WinStatusCodes SubStatus
|
||||
);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = true)]
|
||||
public static extern WinStatusCodes LsaRegisterLogonProcess(
|
||||
IntPtr LogonProcessName,
|
||||
out IntPtr LsaHandle,
|
||||
out ulong SecurityMode
|
||||
);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern WinStatusCodes LsaLookupAuthenticationPackage([In] IntPtr LsaHandle, [In] ref LSA_STRING PackageName, [Out] out UInt32 AuthenticationPackage);
|
||||
|
||||
[DllImport("secur32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
internal static extern int LsaConnectUntrusted(
|
||||
[In, Out] ref SafeLsaLogonProcessHandle LsaHandle);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern WinStatusCodes LsaConnectUntrusted([Out] out IntPtr LsaHandle);
|
||||
|
||||
[System.Security.SecurityCritical] // auto-generated
|
||||
internal sealed class SafeLsaLogonProcessHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private SafeLsaLogonProcessHandle() : base(true) { }
|
||||
|
||||
// 0 is an Invalid Handle
|
||||
internal SafeLsaLogonProcessHandle(IntPtr handle) : base(true)
|
||||
{
|
||||
SetHandle(handle);
|
||||
}
|
||||
|
||||
internal static SafeLsaLogonProcessHandle InvalidHandle
|
||||
{
|
||||
get { return new SafeLsaLogonProcessHandle(IntPtr.Zero); }
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
// LsaDeregisterLogonProcess returns an NTSTATUS
|
||||
return LsaDeregisterLogonProcess(handle) >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = true)]
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
internal static extern int LsaDeregisterLogonProcess(IntPtr handle);
|
||||
|
||||
|
||||
public static void CreateNewSession()
|
||||
{
|
||||
var kli = new SECUR32.KERB_INTERACTIVE_LOGON()
|
||||
{
|
||||
MessageType = SECUR32.KERB_LOGON_SUBMIT_TYPE.KerbInteractiveLogon,
|
||||
UserName = "",
|
||||
Password = ""
|
||||
};
|
||||
IntPtr kerbLogInfo;
|
||||
SECUR32.LSA_STRING logonProc = new()
|
||||
{
|
||||
Buffer = Marshal.StringToHGlobalAuto("InstaLogon"),
|
||||
Length = (ushort)Marshal.SizeOf(Marshal.StringToHGlobalAuto("InstaLogon")),
|
||||
MaximumLength = (ushort)Marshal.SizeOf(Marshal.StringToHGlobalAuto("InstaLogon"))
|
||||
};
|
||||
SECUR32.LSA_STRING originName = new()
|
||||
{
|
||||
Buffer = Marshal.StringToHGlobalAuto("InstaLogon"),
|
||||
Length = (ushort)Marshal.SizeOf(Marshal.StringToHGlobalAuto("InstaLogon")),
|
||||
MaximumLength = (ushort)Marshal.SizeOf(Marshal.StringToHGlobalAuto("InstaLogon"))
|
||||
};
|
||||
SECUR32.LSA_STRING authPackage = new()
|
||||
{
|
||||
Buffer = Marshal.StringToHGlobalAuto("MICROSOFT_KERBEROS_NAME_A"),
|
||||
Length = (ushort)Marshal.SizeOf(Marshal.StringToHGlobalAuto("MICROSOFT_KERBEROS_NAME_A")),
|
||||
MaximumLength = (ushort)Marshal.SizeOf(Marshal.StringToHGlobalAuto("MICROSOFT_KERBEROS_NAME_A"))
|
||||
};
|
||||
IntPtr hLogonProc = Marshal.AllocHGlobal(Marshal.SizeOf(logonProc));
|
||||
Marshal.StructureToPtr(logonProc, hLogonProc, false);
|
||||
ADVAPI32.AllocateLocallyUniqueId(out IntPtr pluid);
|
||||
LsaConnectUntrusted(out IntPtr lsaHan);
|
||||
//SECUR32.LsaRegisterLogonProcess(hLogonProc, out lsaHan, out secMode);
|
||||
SECUR32.LsaLookupAuthenticationPackage(lsaHan, ref authPackage, out uint authPackID);
|
||||
|
||||
kerbLogInfo = Marshal.AllocHGlobal(Marshal.SizeOf(kli));
|
||||
Marshal.StructureToPtr(kli, kerbLogInfo, false);
|
||||
|
||||
var ts = new SECUR32.TOKEN_SOURCE("Insta");
|
||||
SECUR32.LsaLogonUser(
|
||||
lsaHan,
|
||||
ref originName,
|
||||
SECUR32.SecurityLogonType.Interactive,
|
||||
authPackID,
|
||||
kerbLogInfo,
|
||||
(uint)Marshal.SizeOf(kerbLogInfo),
|
||||
IntPtr.Zero,
|
||||
ref ts,
|
||||
out IntPtr profBuf,
|
||||
out uint profBufLen,
|
||||
out long logonID,
|
||||
out IntPtr logonToken,
|
||||
out QUOTA_LIMITS quotas,
|
||||
out WinStatusCodes subStatus);
|
||||
}
|
||||
}
|
||||
51
src/Remote/Insight.Remote.Shared/Native/Windows/Shlwapi.cs
Normal file
51
src/Remote/Insight.Remote.Shared/Native/Windows/Shlwapi.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Windows;
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-isos
|
||||
public class Shlwapi
|
||||
{
|
||||
[DllImport("shlwapi.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool IsOS(OsType osType);
|
||||
}
|
||||
|
||||
public enum OsType
|
||||
{
|
||||
OS_WINDOWS = 0,
|
||||
OS_NT = 1,
|
||||
OS_WIN95ORGREATER = 2,
|
||||
OS_NT4ORGREATER = 3,
|
||||
OS_WIN98ORGREATER = 5,
|
||||
OS_WIN98_GOLD = 6,
|
||||
OS_WIN2000ORGREATER = 7,
|
||||
OS_WIN2000PRO = 8,
|
||||
OS_WIN2000SERVER = 9,
|
||||
OS_WIN2000ADVSERVER = 10,
|
||||
OS_WIN2000DATACENTER = 11,
|
||||
OS_WIN2000TERMINAL = 12,
|
||||
OS_EMBEDDED = 13,
|
||||
OS_TERMINALCLIENT = 14,
|
||||
OS_TERMINALREMOTEADMIN = 15,
|
||||
OS_WIN95_GOLD = 16,
|
||||
OS_MEORGREATER = 17,
|
||||
OS_XPORGREATER = 18,
|
||||
OS_HOME = 19,
|
||||
OS_PROFESSIONAL = 20,
|
||||
OS_DATACENTER = 21,
|
||||
OS_ADVSERVER = 22,
|
||||
OS_SERVER = 23,
|
||||
OS_TERMINALSERVER = 24,
|
||||
OS_PERSONALTERMINALSERVER = 25,
|
||||
OS_FASTUSERSWITCHING = 26,
|
||||
OS_WELCOMELOGONUI = 27,
|
||||
OS_DOMAINMEMBER = 28,
|
||||
OS_ANYSERVER = 29,
|
||||
OS_WOW6432 = 30,
|
||||
OS_WEBSERVER = 31,
|
||||
OS_SMALLBUSINESSSERVER = 32,
|
||||
OS_TABLETPC = 33,
|
||||
OS_SERVERADMINUI = 34,
|
||||
OS_MEDIACENTER = 35,
|
||||
OS_APPLIANCE = 36,
|
||||
}
|
||||
1336
src/Remote/Insight.Remote.Shared/Native/Windows/User32.cs
Normal file
1336
src/Remote/Insight.Remote.Shared/Native/Windows/User32.cs
Normal file
File diff suppressed because it is too large
Load diff
78
src/Remote/Insight.Remote.Shared/Native/Windows/WTSAPI32.cs
Normal file
78
src/Remote/Insight.Remote.Shared/Native/Windows/WTSAPI32.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Windows;
|
||||
|
||||
public static class WTSAPI32
|
||||
{
|
||||
public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
|
||||
|
||||
public enum WTS_CONNECTSTATE_CLASS
|
||||
{
|
||||
WTSActive,
|
||||
WTSConnected,
|
||||
WTSConnectQuery,
|
||||
WTSShadow,
|
||||
WTSDisconnected,
|
||||
WTSIdle,
|
||||
WTSListen,
|
||||
WTSReset,
|
||||
WTSDown,
|
||||
WTSInit
|
||||
}
|
||||
|
||||
public enum WTS_INFO_CLASS
|
||||
{
|
||||
WTSInitialProgram,
|
||||
WTSApplicationName,
|
||||
WTSWorkingDirectory,
|
||||
WTSOEMId,
|
||||
WTSSessionId,
|
||||
WTSUserName,
|
||||
WTSWinStationName,
|
||||
WTSDomainName,
|
||||
WTSConnectState,
|
||||
WTSClientBuildNumber,
|
||||
WTSClientName,
|
||||
WTSClientDirectory,
|
||||
WTSClientProductId,
|
||||
WTSClientHardwareId,
|
||||
WTSClientAddress,
|
||||
WTSClientDisplay,
|
||||
WTSClientProtocolType,
|
||||
WTSIdleTime,
|
||||
WTSLogonTime,
|
||||
WTSIncomingBytes,
|
||||
WTSOutgoingBytes,
|
||||
WTSIncomingFrames,
|
||||
WTSOutgoingFrames,
|
||||
WTSClientInfo,
|
||||
WTSSessionInfo
|
||||
}
|
||||
|
||||
|
||||
[DllImport("wtsapi32.dll", SetLastError = true)]
|
||||
public static extern int WTSEnumerateSessions(
|
||||
IntPtr hServer,
|
||||
int Reserved,
|
||||
int Version,
|
||||
ref IntPtr ppSessionInfo,
|
||||
ref int pCount);
|
||||
|
||||
[DllImport("wtsapi32.dll", ExactSpelling = true, SetLastError = false)]
|
||||
public static extern void WTSFreeMemory(IntPtr memory);
|
||||
|
||||
[DllImport("Wtsapi32.dll")]
|
||||
public static extern bool WTSQuerySessionInformation(IntPtr hServer, uint sessionId, WTS_INFO_CLASS wtsInfoClass, out IntPtr ppBuffer, out uint pBytesReturned);
|
||||
|
||||
[DllImport("wtsapi32.dll", SetLastError = true)]
|
||||
static extern IntPtr WTSOpenServer(string pServerName);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct WTS_SESSION_INFO
|
||||
{
|
||||
public uint SessionID;
|
||||
[MarshalAs(UnmanagedType.LPStr)]
|
||||
public string pWinStationName;
|
||||
public WTS_CONNECTSTATE_CLASS State;
|
||||
}
|
||||
}
|
||||
285
src/Remote/Insight.Remote.Shared/Native/Windows/Win32Interop.cs
Normal file
285
src/Remote/Insight.Remote.Shared/Native/Windows/Win32Interop.cs
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using static Insight.Remote.Shared.Native.Windows.ADVAPI32;
|
||||
using static Insight.Remote.Shared.Native.Windows.User32;
|
||||
|
||||
namespace Insight.Remote.Shared.Native.Windows;
|
||||
|
||||
// TODO: Use https://github.com/dotnet/pinvoke for all p/invokes. Remove signatures from this project.
|
||||
public class Win32Interop
|
||||
{
|
||||
private static IntPtr _lastInputDesktop;
|
||||
|
||||
public static List<WindowsSessionDto> GetActiveSessions()
|
||||
{
|
||||
var sessions = new List<WindowsSessionDto>();
|
||||
var consoleSessionId = Kernel32.WTSGetActiveConsoleSessionId();
|
||||
sessions.Add(new WindowsSessionDto()
|
||||
{
|
||||
Id = consoleSessionId,
|
||||
Type = WindowsSessionType.Console,
|
||||
Name = "Console",
|
||||
Username = GetUsernameFromSessionId(consoleSessionId)
|
||||
});
|
||||
|
||||
IntPtr ppSessionInfo = IntPtr.Zero;
|
||||
var count = 0;
|
||||
var enumSessionResult = WTSAPI32.WTSEnumerateSessions(WTSAPI32.WTS_CURRENT_SERVER_HANDLE, 0, 1, ref ppSessionInfo, ref count);
|
||||
var dataSize = Marshal.SizeOf(typeof(WTSAPI32.WTS_SESSION_INFO));
|
||||
var current = ppSessionInfo;
|
||||
|
||||
if (enumSessionResult != 0)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var wtsInfo = Marshal.PtrToStructure(current, typeof(WTSAPI32.WTS_SESSION_INFO));
|
||||
if (wtsInfo is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var sessionInfo = (WTSAPI32.WTS_SESSION_INFO)wtsInfo;
|
||||
current += dataSize;
|
||||
if (sessionInfo.State == WTSAPI32.WTS_CONNECTSTATE_CLASS.WTSActive && sessionInfo.SessionID != consoleSessionId)
|
||||
{
|
||||
|
||||
sessions.Add(new WindowsSessionDto()
|
||||
{
|
||||
Id = sessionInfo.SessionID,
|
||||
Name = sessionInfo.pWinStationName,
|
||||
Type = WindowsSessionType.RDP,
|
||||
Username = GetUsernameFromSessionId(sessionInfo.SessionID)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sessions;
|
||||
}
|
||||
|
||||
public static string GetCommandLine()
|
||||
{
|
||||
var commandLinePtr = Kernel32.GetCommandLine();
|
||||
return Marshal.PtrToStringAuto(commandLinePtr) ?? string.Empty;
|
||||
}
|
||||
|
||||
public static bool GetCurrentDesktop(out string desktopName)
|
||||
{
|
||||
var inputDesktop = OpenInputDesktop();
|
||||
try
|
||||
{
|
||||
byte[] deskBytes = new byte[256];
|
||||
if (!GetUserObjectInformationW(inputDesktop, UOI_NAME, deskBytes, 256, out uint lenNeeded))
|
||||
{
|
||||
desktopName = string.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
desktopName = Encoding.Unicode.GetString(deskBytes.Take((int)lenNeeded).ToArray()).Replace("\0", "");
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseDesktop(inputDesktop);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetUsernameFromSessionId(uint sessionId)
|
||||
{
|
||||
var username = string.Empty;
|
||||
|
||||
if (WTSAPI32.WTSQuerySessionInformation(IntPtr.Zero, sessionId, WTSAPI32.WTS_INFO_CLASS.WTSUserName, out var buffer, out var strLen) && strLen > 1)
|
||||
{
|
||||
username = Marshal.PtrToStringAnsi(buffer);
|
||||
WTSAPI32.WTSFreeMemory(buffer);
|
||||
}
|
||||
|
||||
return username ?? string.Empty;
|
||||
}
|
||||
|
||||
public static IntPtr OpenInputDesktop()
|
||||
{
|
||||
return User32.OpenInputDesktop(0, true, ACCESS_MASK.GENERIC_ALL);
|
||||
}
|
||||
|
||||
public static bool CreateInteractiveSystemProcess(
|
||||
string commandLine,
|
||||
int targetSessionId,
|
||||
bool forceConsoleSession,
|
||||
string desktopName,
|
||||
bool hiddenWindow,
|
||||
out PROCESS_INFORMATION procInfo)
|
||||
{
|
||||
uint winlogonPid = 0;
|
||||
var hUserTokenDup = IntPtr.Zero;
|
||||
var hPToken = IntPtr.Zero;
|
||||
var hProcess = IntPtr.Zero;
|
||||
|
||||
procInfo = new PROCESS_INFORMATION();
|
||||
|
||||
// If not force console, find target session. If not present,
|
||||
// use last active session.
|
||||
var dwSessionId = Kernel32.WTSGetActiveConsoleSessionId();
|
||||
if (!forceConsoleSession)
|
||||
{
|
||||
var activeSessions = GetActiveSessions();
|
||||
if (activeSessions.Any(x => x.Id == targetSessionId))
|
||||
{
|
||||
dwSessionId = (uint)targetSessionId;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwSessionId = activeSessions.Last().Id;
|
||||
}
|
||||
}
|
||||
|
||||
// Obtain the process ID of the winlogon process that is running within the currently active session.
|
||||
var processes = Process.GetProcessesByName("winlogon");
|
||||
foreach (Process p in processes)
|
||||
{
|
||||
if ((uint)p.SessionId == dwSessionId)
|
||||
{
|
||||
winlogonPid = (uint)p.Id;
|
||||
}
|
||||
}
|
||||
|
||||
// Obtain a handle to the winlogon process.
|
||||
hProcess = Kernel32.OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);
|
||||
|
||||
// Obtain a handle to the access token of the winlogon process.
|
||||
if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken))
|
||||
{
|
||||
Kernel32.CloseHandle(hProcess);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser.
|
||||
var sa = new SECURITY_ATTRIBUTES();
|
||||
sa.Length = Marshal.SizeOf(sa);
|
||||
|
||||
// Copy the access token of the winlogon process; the newly created token will be a primary token.
|
||||
if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out hUserTokenDup))
|
||||
{
|
||||
Kernel32.CloseHandle(hProcess);
|
||||
Kernel32.CloseHandle(hPToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
// By default, CreateProcessAsUser creates a process on a non-interactive window station, meaning
|
||||
// the window station has a desktop that is invisible and the process is incapable of receiving
|
||||
// user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user
|
||||
// interaction with the new process.
|
||||
var si = new STARTUPINFO();
|
||||
si.cb = Marshal.SizeOf(si);
|
||||
si.lpDesktop = @"winsta0\" + desktopName;
|
||||
|
||||
// Flags that specify the priority and creation method of the process.
|
||||
uint dwCreationFlags;
|
||||
if (hiddenWindow)
|
||||
{
|
||||
dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW;
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE;
|
||||
}
|
||||
|
||||
// Create a new process in the current user's logon session.
|
||||
var result = CreateProcessAsUser(
|
||||
hUserTokenDup,
|
||||
null,
|
||||
commandLine,
|
||||
ref sa,
|
||||
ref sa,
|
||||
false,
|
||||
dwCreationFlags,
|
||||
IntPtr.Zero,
|
||||
null,
|
||||
ref si,
|
||||
out procInfo);
|
||||
|
||||
// Invalidate the handles.
|
||||
Kernel32.CloseHandle(hProcess);
|
||||
Kernel32.CloseHandle(hPToken);
|
||||
Kernel32.CloseHandle(hUserTokenDup);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void SetMonitorState(MonitorState state)
|
||||
{
|
||||
SendMessage(0xFFFF, 0x112, 0xF170, (int)state);
|
||||
}
|
||||
|
||||
public static MessageBoxResult ShowMessageBox(IntPtr owner,
|
||||
string message,
|
||||
string caption,
|
||||
MessageBoxType messageBoxType)
|
||||
{
|
||||
return (MessageBoxResult)MessageBox(owner, message, caption, (long)messageBoxType);
|
||||
}
|
||||
|
||||
public static bool SwitchToInputDesktop()
|
||||
{
|
||||
try
|
||||
{
|
||||
CloseDesktop(_lastInputDesktop);
|
||||
var inputDesktop = OpenInputDesktop();
|
||||
|
||||
if (inputDesktop == IntPtr.Zero)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var result = SetThreadDesktop(inputDesktop) && SwitchDesktop(inputDesktop);
|
||||
_lastInputDesktop = inputDesktop;
|
||||
return result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetConsoleWindowVisibility(bool isVisible)
|
||||
{
|
||||
var handle = Kernel32.GetConsoleWindow();
|
||||
|
||||
if (isVisible)
|
||||
{
|
||||
ShowWindow(handle, (int)SW.SW_SHOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowWindow(handle, (int)SW.SW_HIDE);
|
||||
}
|
||||
|
||||
Kernel32.CloseHandle(handle);
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
public class WindowsSessionDto
|
||||
{
|
||||
[DataMember(Name = "ID")]
|
||||
public uint Id { get; set; }
|
||||
|
||||
[DataMember(Name = "Name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[DataMember(Name = "Type")]
|
||||
public WindowsSessionType Type { get; set; }
|
||||
|
||||
[DataMember(Name = "Username")]
|
||||
public string Username { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
public enum WindowsSessionType
|
||||
{
|
||||
Console = 1,
|
||||
RDP = 2
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue