Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Launch your app into session 1 using a service helper application written in C#

0.00/5 (No votes)
13 May 2007 1  
Launch your application into session 1 using a service in session 0 (C#) under the local system account

Introduction

This is the same article which I have written earlier in Native C++ code. (Launch your application from session 0 to session 1 in Vista using a service helper application at VistaSessions.asp)

Luzius Kalt mailed me a C# version of the service which would work well for those who wanted the code on the .NET platform.

Since I got many requests to post the article in .NET, I am posting the code I received from Luzius.

To acknowledge his efforts, I am posting this as a separate article.

Using the code

The heart of the application logic is the service. This is what launches the helper application into session 1.

Hence only the service has been rewritten in C#.

The code rewritten in C# uses PINVOKE to execute native API's.

The application Custom message sender which sends the message to the service to launch the application as well as the code which will access HKCU in the registry (refer to my article VistaSessions.asp) is still in native code.

I will update that too soon.

The following structures and API's from Win32 have been declared in C#

// Structure for the CreateProcessAsuser API

[StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public int Length;
            public IntPtr lpSecurityDescriptor;
            public bool bInheritHandle;
        }
//Structure for the DuplicateTokenEx API

        enum TOKEN_TYPE : int
        {
            TokenPrimary = 1,
            TokenImpersonation = 2
        }
//Structure for the SetTokenInformation API

        public enum TOKEN_INFORMATION_CLASS : int
        {
            TokenUser = 1,
            TokenGroups,
            TokenPrivileges,
            TokenOwner,
            TokenPrimaryGroup,
            TokenDefaultDacl,
            TokenSource,
            TokenType,
            TokenImpersonationLevel,
            TokenStatistics,
            TokenRestrictedSids,
            TokenSessionId,
            TokenGroupsAndPrivileges,
            TokenSessionReference,
            TokenSandBoxInert,
            TokenAuditPolicy,
            TokenOrigin,
            MaxTokenInfoClass  
        // MaxTokenInfoClass should always be the last enum

        }
//Structure for CreateProcess API

        [StructLayout(LayoutKind.Sequential)]
        public struct STARTUPINFO
        {
            public int cb;
            public String lpReserved;
            public String lpDesktop;
            public String lpTitle;
            public uint dwX;
            public uint dwY;
            public uint dwXSize;
            public uint dwYSize;
            public uint dwXCountChars;
            public uint dwYCountChars;
            public uint dwFillAttribute;
            public uint dwFlags;
            public short wShowWindow;
            public short cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }
//Structure for CreateProcess API

        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public uint dwProcessId;
            public uint dwThreadId;
        }
//Structure for LookupPriveleges API

       [StructLayout(LayoutKind.Sequential)]
        internal struct LUID
        {
            public int LowPart;
            public int HighPart;
        }//end struct

//For the TOKEN PRIVILEGES STRUCTURE

        [StructLayout(LayoutKind.Sequential)]
        internal struct LUID_AND_ATRIBUTES
        {
            public LUID Luid;
            public int Attributes;
        }//end struct

//Structure for the AdjustTokenPrivileges API


        [StructLayout(LayoutKind.Sequential)]
        internal struct TOKEN_PRIVILEGES
        {
            internal int PrivilegeCount;
            //LUID_AND_ATRIBUTES

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            internal int[] Privileges;
        }

//Defined for Token rights


        public const int READ_CONTROL = 0x00020000;
        public const int STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        public const int STANDARD_RIGHTS_READ = READ_CONTROL;
        public const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
        public const int STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
        public const int STANDARD_RIGHTS_ALL = 0x001F0000;
        public const int SPECIFIC_RIGHTS_ALL = 0x0000FFFF;
        public const int TOKEN_ASSIGN_PRIMARY = 0x0001;
        public const int TOKEN_DUPLICATE = 0x0002;
        public const int TOKEN_IMPERSONATE = 0x0004;
        public const int TOKEN_QUERY = 0x0008;
        public const int TOKEN_QUERY_SOURCE = 0x0010;
        public const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
        public const int TOKEN_ADJUST_GROUPS = 0x0040;
        public const int TOKEN_ADJUST_DEFAULT = 0x0080;
        public const int TOKEN_ADJUST_SESSIONID = 0x0100;
        public const int TOKEN_ALL_ACCESS_P = (STANDARD_RIGHTS_REQUIRED |
                                      TOKEN_ASSIGN_PRIMARY |
                                      TOKEN_DUPLICATE |
                                      TOKEN_IMPERSONATE |
                                      TOKEN_QUERY |
                                      TOKEN_QUERY_SOURCE |
                                      TOKEN_ADJUST_PRIVILEGES |
                                      TOKEN_ADJUST_GROUPS |
                                      TOKEN_ADJUST_DEFAULT);
        public const int TOKEN_ALL_ACCESS = TOKEN_ALL_ACCESS_P | 
                      TOKEN_ADJUST_SESSIONID;
        public const int TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY;
        public const int TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
                                      TOKEN_ADJUST_PRIVILEGES |
                                      TOKEN_ADJUST_GROUPS |
                                      TOKEN_ADJUST_DEFAULT;
        public const int TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE;

//Defined for Process Rights

        public const uint MAXIMUM_ALLOWED = 0x2000000;
        public const int CREATE_NEW_PROCESS_GROUP = 0x00000200;
        public const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
        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 int CREATE_NEW_CONSOLE = 0x00000010;
        public const string SE_DEBUG_NAME = "SeDebugPrivilege";
        public const string SE_RESTORE_NAME = "SeRestorePrivilege";
        public const string SE_BACKUP_NAME = "SeBackupPrivilege";
        public const int SE_PRIVILEGE_ENABLED = 0x0002;
        public const int ERROR_NOT_ALL_ASSIGNED = 1300;

//structure for the Process32First API

   
[StructLayout(LayoutKind.Sequential)]
        private struct PROCESSENTRY32
        {
            public uint dwSize;
            public uint cntUsage;
            public uint th32ProcessID;
            public IntPtr th32DefaultHeapID;
            public uint th32ModuleID;
            public uint cntThreads;
            public uint th32ParentProcessID;
            public int pcPriClassBase;
            public uint dwFlags;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szExeFile;
        }      
Rest of the code is straightforward. You can refer to my previous article to understand the core logic. You are free to use the code. You can contact me at jaisvar@gmail.com for more details. I am in the process of writing my second article about UAC tweaks soon.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here