Advertisement
Guest User

Untitled

a guest
Dec 9th, 2015
406
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.15 KB | None | 0 0
  1. public static class ProcessAsCurrentUser
  2.     {
  3.  
  4.         /// <summary>
  5.         /// Connection state of a session.
  6.         /// </summary>
  7.         public enum ConnectionState
  8.         {
  9.             /// <summary>
  10.             /// A user is logged on to the session.
  11.             /// </summary>
  12.             Active,
  13.             /// <summary>
  14.             /// A client is connected to the session.
  15.             /// </summary>
  16.             Connected,
  17.             /// <summary>
  18.             /// The session is in the process of connecting to a client.
  19.             /// </summary>
  20.             ConnectQuery,
  21.             /// <summary>
  22.             /// This session is shadowing another session.
  23.             /// </summary>
  24.             Shadowing,
  25.             /// <summary>
  26.             /// The session is active, but the client has disconnected from it.
  27.             /// </summary>
  28.             Disconnected,
  29.             /// <summary>
  30.             /// The session is waiting for a client to connect.
  31.             /// </summary>
  32.             Idle,
  33.             /// <summary>
  34.             /// The session is listening for connections.
  35.             /// </summary>
  36.             Listening,
  37.             /// <summary>
  38.             /// The session is being reset.
  39.             /// </summary>
  40.             Reset,
  41.             /// <summary>
  42.             /// The session is down due to an error.
  43.             /// </summary>
  44.             Down,
  45.             /// <summary>
  46.             /// The session is initializing.
  47.             /// </summary>
  48.             Initializing
  49.         }
  50.  
  51.  
  52.         [StructLayout(LayoutKind.Sequential)]
  53.         class SECURITY_ATTRIBUTES
  54.         {
  55.             public int nLength;
  56.             public IntPtr lpSecurityDescriptor;
  57.             public int bInheritHandle;
  58.         }
  59.  
  60.  
  61.         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  62.         struct STARTUPINFO
  63.         {
  64.             public Int32 cb;
  65.             public string lpReserved;
  66.             public string lpDesktop;
  67.             public string lpTitle;
  68.             public Int32 dwX;
  69.             public Int32 dwY;
  70.             public Int32 dwXSize;
  71.             public Int32 dwYSize;
  72.             public Int32 dwXCountChars;
  73.             public Int32 dwYCountChars;
  74.             public Int32 dwFillAttribute;
  75.             public Int32 dwFlags;
  76.             public Int16 wShowWindow;
  77.             public Int16 cbReserved2;
  78.             public IntPtr lpReserved2;
  79.             public IntPtr hStdInput;
  80.             public IntPtr hStdOutput;
  81.             public IntPtr hStdError;
  82.         }
  83.  
  84.         [StructLayout(LayoutKind.Sequential)]
  85.         internal struct PROCESS_INFORMATION
  86.         {
  87.             public IntPtr hProcess;
  88.             public IntPtr hThread;
  89.             public int dwProcessId;
  90.             public int dwThreadId;
  91.         }
  92.  
  93.         enum LOGON_TYPE
  94.         {
  95.             LOGON32_LOGON_INTERACTIVE = 2,
  96.             LOGON32_LOGON_NETWORK,
  97.             LOGON32_LOGON_BATCH,
  98.             LOGON32_LOGON_SERVICE,
  99.             LOGON32_LOGON_UNLOCK = 7,
  100.             LOGON32_LOGON_NETWORK_CLEARTEXT,
  101.             LOGON32_LOGON_NEW_CREDENTIALS
  102.         }
  103.  
  104.         enum LOGON_PROVIDER
  105.         {
  106.             LOGON32_PROVIDER_DEFAULT,
  107.             LOGON32_PROVIDER_WINNT35,
  108.             LOGON32_PROVIDER_WINNT40,
  109.             LOGON32_PROVIDER_WINNT50
  110.         }
  111.  
  112.         [Flags]
  113.         enum CreateProcessFlags : uint
  114.         {
  115.             CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
  116.             CREATE_DEFAULT_ERROR_MODE = 0x04000000,
  117.             CREATE_NEW_CONSOLE = 0x00000010,
  118.             CREATE_NEW_PROCESS_GROUP = 0x00000200,
  119.             CREATE_NO_WINDOW = 0x08000000,
  120.             CREATE_PROTECTED_PROCESS = 0x00040000,
  121.             CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
  122.             CREATE_SEPARATE_WOW_VDM = 0x00000800,
  123.             CREATE_SHARED_WOW_VDM = 0x00001000,
  124.             CREATE_SUSPENDED = 0x00000004,
  125.             CREATE_UNICODE_ENVIRONMENT = 0x00000400,
  126.             DEBUG_ONLY_THIS_PROCESS = 0x00000002,
  127.             DEBUG_PROCESS = 0x00000001,
  128.             DETACHED_PROCESS = 0x00000008,
  129.             EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
  130.             INHERIT_PARENT_AFFINITY = 0x00010000
  131.         }
  132.  
  133.         enum WTS_INFO_CLASS
  134.         {
  135.             WTSInitialProgram,
  136.             WTSApplicationName,
  137.             WTSWorkingDirectory,
  138.             WTSOEMId,
  139.             WTSSessionId,
  140.             WTSUserName,
  141.             WTSWinStationName,
  142.             WTSDomainName,
  143.             WTSConnectState,
  144.             WTSClientBuildNumber,
  145.             WTSClientName,
  146.             WTSClientDirectory,
  147.             WTSClientProductId,
  148.             WTSClientHardwareId,
  149.             WTSClientAddress,
  150.             WTSClientDisplay,
  151.             WTSClientProtocolType,
  152.             WTSIdleTime,
  153.             WTSLogonTime,
  154.             WTSIncomingBytes,
  155.             WTSOutgoingBytes,
  156.             WTSIncomingFrames,
  157.             WTSOutgoingFrames,
  158.             WTSClientInfo,
  159.             WTSSessionInfo
  160.         };
  161.  
  162.         [StructLayout(LayoutKind.Sequential)]
  163.         public struct WTS_SESSION_INFO
  164.         {
  165.             public int SessionID;
  166.             [MarshalAs(UnmanagedType.LPTStr)]
  167.             public string WinStationName;
  168.             public ConnectionState State;
  169.         }
  170.  
  171.         [DllImport("wtsapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  172.         public static extern Int32 WTSEnumerateSessions(IntPtr hServer, int reserved, int version,
  173.                                                         ref IntPtr sessionInfo, ref int count);
  174.        
  175.         [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUserW", SetLastError = true, CharSet = CharSet.Auto)]
  176.         static extern bool CreateProcessAsUser(
  177.             IntPtr hToken,
  178.             string lpApplicationName,
  179.             string lpCommandLine,
  180.             IntPtr lpProcessAttributes,
  181.             IntPtr lpThreadAttributes,
  182.             bool bInheritHandles,
  183.             UInt32 dwCreationFlags,
  184.             IntPtr lpEnvironment,
  185.             string lpCurrentDirectory,
  186.             ref STARTUPINFO lpStartupInfo,
  187.             out PROCESS_INFORMATION lpProcessInformation);
  188.  
  189.         [DllImport("wtsapi32.dll")]
  190.         public static extern void WTSFreeMemory(IntPtr memory);
  191.  
  192.         [DllImport("kernel32.dll")]
  193.         private static extern UInt32 WTSGetActiveConsoleSessionId();
  194.  
  195.         [DllImport("wtsapi32.dll", SetLastError = true)]
  196.         static extern int WTSQueryUserToken(UInt32 sessionId, out IntPtr Token);
  197.  
  198.         [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  199.         public extern static bool DuplicateTokenEx(
  200.             IntPtr hExistingToken,
  201.             uint dwDesiredAccess,
  202.             IntPtr lpTokenAttributes,
  203.             int ImpersonationLevel,
  204.             int TokenType,
  205.             out IntPtr phNewToken);
  206.        
  207.         [DllImport("Wtsapi32.dll", SetLastError = true)]
  208.         static extern bool WTSQuerySessionInformation(
  209.             IntPtr hServer,
  210.             uint sessionId,
  211.             WTS_INFO_CLASS wtsInfoClass,
  212.             out IntPtr ppBuffer,
  213.             out uint pBytesReturned
  214.         );        
  215.  
  216.         private const int TokenImpersonation = 2;
  217.         private const int SecurityIdentification = 1;
  218.         private const int MAXIMUM_ALLOWED = 0x2000000;
  219.         private const int TOKEN_DUPLICATE = 0x2;
  220.         private const int TOKEN_QUERY = 0x00000008;
  221.  
  222.         /// <summary>
  223.         /// Launches a process for the current logged on user if there are any.
  224.         /// If none, return false as well as in case of
  225.         ///
  226.         /// ##### !!! BEWARE !!! ####  ------------------------------------------
  227.         /// This code will only work when running in a windows service (where it is really needed)
  228.         /// so in case you need to test it, it needs to run in the service. Reason
  229.         /// is a security privileg which only services have (SE_??? something, cant remember)!
  230.         /// </summary>
  231.         /// <param name="processExe"></param>
  232.         /// <returns></returns>
  233.         public static bool CreateProcessAsCurrentUser(string processExe, string commandLine, out int processId)
  234.         {
  235.             processId = -1;
  236.             IntPtr duplicate = new IntPtr();
  237.             STARTUPINFO info = new STARTUPINFO();
  238.             PROCESS_INFORMATION procInfo = new PROCESS_INFORMATION();
  239.  
  240.             Debug.WriteLine(string.Format("CreateProcessAsCurrentUser. processExe: " + processExe));
  241.  
  242.             IntPtr p = GetCurrentUserToken();
  243.            
  244.             bool result = DuplicateTokenEx(p, MAXIMUM_ALLOWED | TOKEN_QUERY | TOKEN_DUPLICATE, IntPtr.Zero, SecurityIdentification, SecurityIdentification, out duplicate);
  245.             Debug.WriteLine(string.Format("DuplicateTokenEx result: {0}", result));
  246.             Debug.WriteLine(string.Format("duplicate: {0}", duplicate));            
  247.            
  248.             if (result)
  249.             {
  250.                 result = CreateProcessAsUser(duplicate, processExe, commandLine,
  251.                     IntPtr.Zero, IntPtr.Zero, false, (UInt32)CreateProcessFlags.CREATE_NEW_CONSOLE, IntPtr.Zero, null,
  252.                     ref info, out procInfo);
  253.                 processId = procInfo.dwProcessId;
  254.                 Debug.WriteLine(string.Format("CreateProcessAsUser result: {0}", result));                
  255.             }
  256.  
  257.  
  258.             if (p.ToInt32() != 0)
  259.             {
  260.                 Marshal.Release(p);
  261.                 Debug.WriteLine(string.Format("Released handle p: {0}", p));
  262.             }
  263.  
  264.  
  265.             if (duplicate.ToInt32() != 0)
  266.             {
  267.                 Marshal.Release(duplicate);
  268.                 Debug.WriteLine(string.Format("Released handle duplicate: {0}", duplicate));
  269.             }
  270.  
  271.  
  272.  
  273.             return result;
  274.         }
  275.  
  276.         public static int GetCurrentSessionId()
  277.         {
  278.             uint sessionId = WTSGetActiveConsoleSessionId();
  279.             Debug.WriteLine(string.Format("sessionId: {0}", sessionId));
  280.  
  281.             if (sessionId == 0xFFFFFFFF)
  282.                 return -1;
  283.             else
  284.                 return (int)sessionId;
  285.         }
  286.  
  287.  
  288.         public static string GetCurrentUsername()
  289.         {            
  290.             int sessionId = GetCurrentSessionId();
  291.             if (sessionId < 0)
  292.                 return null;
  293.  
  294.             return GetUsernameBySessionId((uint)sessionId);
  295.         }
  296.        
  297.         public static string GetUsernameBySessionId(uint sessionId)
  298.         {
  299.             IntPtr bufferPtr = IntPtr.Zero;
  300.             uint bufferLength = 0;
  301.  
  302.             if (!WTSQuerySessionInformation(IntPtr.Zero, sessionId, WTS_INFO_CLASS.WTSUserName, out bufferPtr, out bufferLength))
  303.                 return null;
  304.  
  305.             string ret = Marshal.PtrToStringAnsi(bufferPtr);
  306.             WTSFreeMemory(bufferPtr);
  307.             return ret;
  308.         }        
  309.  
  310.         public static bool IsUserLoggedOn()
  311.         {
  312.             List<WTS_SESSION_INFO> wtsSessionInfos = ListSessions();
  313.             Debug.WriteLine(string.Format("Number of sessions: {0}", wtsSessionInfos.Count));
  314.             return wtsSessionInfos.Where(x => x.State == ConnectionState.Active).Count() > 0;
  315.         }
  316.  
  317.         private static IntPtr GetCurrentUserToken()
  318.         {
  319.             List<WTS_SESSION_INFO> wtsSessionInfos = ListSessions();
  320.             int sessionId = wtsSessionInfos.Where(x => x.State == ConnectionState.Active).FirstOrDefault().SessionID;
  321.             //int sessionId = GetCurrentSessionId();            
  322.  
  323.             Debug.WriteLine(string.Format("sessionId: {0}", sessionId));
  324.             if (sessionId == int.MaxValue)
  325.             {
  326.                 return IntPtr.Zero;
  327.             }
  328.             else
  329.             {
  330.                 IntPtr p = new IntPtr();
  331.                 int result = WTSQueryUserToken((UInt32)sessionId, out p);
  332.                 Debug.WriteLine(string.Format("WTSQueryUserToken result: {0}", result));
  333.                 Debug.WriteLine(string.Format("WTSQueryUserToken p: {0}", p));
  334.  
  335.                
  336.  
  337.                 return p;
  338.             }
  339.         }
  340.  
  341.         public static List<WTS_SESSION_INFO> ListSessions()
  342.         {
  343.             IntPtr server = IntPtr.Zero;
  344.             List<WTS_SESSION_INFO> ret = new List<WTS_SESSION_INFO>();
  345.  
  346.             try
  347.             {
  348.                 IntPtr ppSessionInfo = IntPtr.Zero;
  349.  
  350.                 Int32 count = 0;
  351.                 Int32 retval = WTSEnumerateSessions(IntPtr.Zero, 0, 1, ref ppSessionInfo, ref count);
  352.                 Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
  353.  
  354.                 Int64 current = (int)ppSessionInfo;
  355.  
  356.                 if (retval != 0)
  357.                 {
  358.                     for (int i = 0; i < count; i++)
  359.                     {
  360.                         WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
  361.                         current += dataSize;
  362.  
  363.                         ret.Add(si);
  364.                     }
  365.                    
  366.                     WTSFreeMemory(ppSessionInfo);
  367.                 }
  368.             }
  369.             catch (Exception exception)
  370.             {
  371.                 Debug.WriteLine(exception.ToString());
  372.             }
  373.  
  374.             return ret;
  375.         }
  376.  
  377.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement