Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Need help in studying this c# class

Posted on 2006-11-01
3
Medium Priority
?
973 Views
Last Modified: 2012-06-27
hi, i got this class from the web. i think it enables a program to execute external application using windows Administrator(or others) account. but as a beginner, its too much for me to grasp. i need to know how to use this class?
basically i want to execute a program as administrator, and let it run without waiting for it to exit.




using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Security.Principal;
using System.Text;

///
/// UserSpecificProcess extends the standard Process object to
/// create new processes under a different user than the calling parent process.
/// Also, the standard output of the child process redirected back to the parent process.
/// This is class is designed to operate inside an ASP.NET web application.
/// The assumption is that the calling thread is operating with an impersonated security token.
/// The this class will change the imperonated security token to a primary token,
/// and call CreateProcessAsUser.
/// A System.Diagnostics.Process object will be returned with appropriate properties set.
/// To use this function, the following security priviliges need to be set for the ASPNET account
/// using the local security policy MMC snap-in. CreateProcessAsUser requirement.
/// "Replace a process level token"/SE_ASSIGNPRIMARYTOKEN_NAME/SeAssignPrimaryTokenPrivilege
/// "Adjust memory quotas for a process"/SE_INCREASE_QUOTA_NAME/SeIncreaseQuotaPrivilege
///
/// This class was designed for .NET 1.1 for operating systems W2k an higher.
/// Any other features or platform support can be implemented by using the .NET reflector and
/// investigating the Process class.
///
public class UserSpecificProcess : Process
{
    [StructLayout(LayoutKind.Sequential)]
    public class CreateProcessStartupInfo
    {
        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;
        public CreateProcessStartupInfo()
        {
            this.cb = Marshal.SizeOf(typeof(CreateProcessStartupInfo));
            this.lpReserved = null;
            this.lpDesktop = null;
            this.lpTitle = null;
            this.dwX = 0;
            this.dwY = 0;
            this.dwXSize = 0;
            this.dwYSize = 0;
            this.dwXCountChars = 0;
            this.dwYCountChars = 0;
            this.dwFillAttribute = 0;
            this.dwFlags = 0;
            this.wShowWindow = 0;
            this.cbReserved2 = 0;
            this.lpReserved2 = IntPtr.Zero;
            this.hStdInput = IntPtr.Zero;
            this.hStdOutput = IntPtr.Zero;
            this.hStdError = IntPtr.Zero;
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public class CreateProcessProcessInformation
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public int dwProcessId;
        public int dwThreadId;
        public CreateProcessProcessInformation()
        {
            this.hProcess = IntPtr.Zero;
            this.hThread = IntPtr.Zero;
            this.dwProcessId = 0;
            this.dwThreadId = 0;
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public class SecurityAttributes
    {
        public int nLength;
        public IntPtr lpSecurityDescriptor;
        public bool bInheritHandle;
        public SecurityAttributes()
        {
            this.nLength = Marshal.SizeOf(typeof(SecurityAttributes));
        }
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
    public static extern bool CloseHandle(HandleRef handle);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CreateProcess([MarshalAs(UnmanagedType.LPTStr)] string lpApplicationName, StringBuilder lpCommandLine, SecurityAttributes lpProcessAttributes, SecurityAttributes lpThreadAttributes, bool bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment, [MarshalAs(UnmanagedType.LPTStr)] string lpCurrentDirectory, CreateProcessStartupInfo lpStartupInfo, CreateProcessProcessInformation lpProcessInformation);

    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern bool CreateProcessAsUserW(IntPtr token, [MarshalAs(UnmanagedType.LPTStr)] string lpApplicationName, [MarshalAs(UnmanagedType.LPTStr)] string lpCommandLine, SecurityAttributes lpProcessAttributes, SecurityAttributes lpThreadAttributes, bool bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment, [MarshalAs(UnmanagedType.LPTStr)] string lpCurrentDirectory, CreateProcessStartupInfo lpStartupInfo, CreateProcessProcessInformation lpProcessInformation);

    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    public static extern IntPtr GetStdHandle(int whichHandle);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, SecurityAttributes lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, HandleRef hTemplateFile);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr CreateNamedPipe(string name, int openMode, int pipeMode, int maxInstances, int outBufSize, int inBufSize, int timeout, SecurityAttributes lpPipeAttributes);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int GetConsoleOutputCP();

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool DuplicateTokenEx(HandleRef hToken, int access, SecurityAttributes tokenAttributes, int impersonationLevel, int tokenType, ref IntPtr hNewToken);

    // WinNT.h ACCESS TYPES
    const int GENERIC_ALL = 0x10000000;

    // WinNT.h enum SECURITY_IMPERSONATION_LEVEL
    const int SECURITY_IMPERSONATION = 2;

    // WinNT.h TOKEN TYPE
    const int TOKEN_PRIMARY = 1;

    // WinBase.h
    const int STD_INPUT_HANDLE = -10;
    const int STD_ERROR_HANDLE = -12;

    // WinBase.h STARTUPINFO
    const int STARTF_USESTDHANDLES = 0x100;

    // Microsoft.Win23.NativeMethods
    static IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);
    public static HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero);

    ///
    /// Starts the process with the security token of the calling thread.
    /// If the security token has a token type of TokenImpersonation,
    /// the token will be duplicated to a primary token before calling
    /// CreateProcessAsUser.
    ///
    /// The process to start.
    public void StartAsUser()
    {
        StartAsUser(WindowsIdentity.GetCurrent().Token);
    }

    ///
    /// Starts the process with the given security token.
    /// If the security token has a token type of TokenImpersonation,
    /// the token will be duplicated to a primary token before calling
    /// CreateProcessAsUser.
    ///
    ///
    public void StartAsUser(IntPtr userToken)
    {
        if (StartInfo.UseShellExecute)
        {
            throw new InvalidOperationException("can't call this with shell execute");
        }

        // just assume that the securityToken is of TokenImpersonation and create a primary.
        IntPtr primayUserToken = CreatePrimaryToken(userToken);

        CreateProcessStartupInfo startupInfo = new CreateProcessStartupInfo();
        CreateProcessProcessInformation processInformation = new CreateProcessProcessInformation();

        IntPtr stdinHandle;
        IntPtr stdoutReadHandle;
        IntPtr stdoutWriteHandle = IntPtr.Zero;
        IntPtr stderrHandle;
        try
        {
            stdinHandle = GetStdHandle(STD_INPUT_HANDLE);
            MyCreatePipe(out stdoutReadHandle, out stdoutWriteHandle, false);
            stderrHandle = GetStdHandle(STD_ERROR_HANDLE);

            //assign handles to startup info
            startupInfo.dwFlags = STARTF_USESTDHANDLES;
            startupInfo.hStdInput = stdinHandle;
            startupInfo.hStdOutput = stdoutWriteHandle;
            startupInfo.hStdError = stderrHandle;

            string commandLine = GetCommandLine();
            int creationFlags = 0;
            IntPtr environment = IntPtr.Zero;
            string workingDirectory = GetWorkingDirectory();

            // create the process or fail trying.
            if (!CreateProcessAsUserW(
            primayUserToken,
            null,
            commandLine,
            null,
            null,
            true,
            creationFlags,
            environment,
            workingDirectory,
            startupInfo,
            processInformation))
            {
                throw new Win32Exception();
            }
        }
        finally
        {
            // close thread handle
            if (processInformation.hThread != INVALID_HANDLE_VALUE)
            {
                CloseHandle(new HandleRef(this, processInformation.hThread));
            }

            // close client stdout handle
            CloseHandle(new HandleRef(this, stdoutWriteHandle));
        }

        // get reader for standard output from the child
        Encoding encoding = Encoding.GetEncoding(GetConsoleOutputCP());
        StreamReader standardOutput = new StreamReader(new FileStream(stdoutReadHandle, FileAccess.Read, true, 0x1000, true), encoding);

        // set this on the object accordingly.
        typeof(Process).InvokeMember("standardOutput",
        BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance,
        null, this, new object[] { standardOutput });

        // scream if a process wasn't started instead of returning false.
        if (processInformation.hProcess == IntPtr.Zero)
        {
            throw new Exception("failed to create process");
        }

        // configure the properties of the Process object correctly
        typeof(Process).InvokeMember("SetProcessHandle",
        BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
        null, this, new object[] { processInformation.hProcess });
        typeof(Process).InvokeMember("SetProcessId",
        BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
        null, this, new object[] { processInformation.dwProcessId });
    }

    ///
    /// Creates a primayToken out of an existing token.
    ///
    ///
    private IntPtr CreatePrimaryToken(IntPtr userToken)
    {
        SecurityAttributes securityAttributes = new SecurityAttributes();
        IntPtr primaryUserToken = IntPtr.Zero;
        if (!DuplicateTokenEx(new HandleRef(this, userToken), GENERIC_ALL, securityAttributes, SECURITY_IMPERSONATION, TOKEN_PRIMARY, ref primaryUserToken))
        {
            throw new Win32Exception();
        }
        return primaryUserToken;
    }

    ///
    /// Gets the appropriate commandLine from the process.
    ///
    ///
    ///
    private string GetCommandLine()
    {
        StringBuilder builder1 = new StringBuilder();
        string text1 = StartInfo.FileName.Trim();
        string text2 = StartInfo.Arguments;
        bool flag1 = text1.StartsWith("\"") && text1.EndsWith("\"");
        if (!flag1)
        {
            builder1.Append("\"");
        }
        builder1.Append(text1);
        if (!flag1)
        {
            builder1.Append("\"");
        }
        if ((text2 != null) && (text2.Length > 0))
        {
            builder1.Append(" ");
            builder1.Append(text2);
        }
        return builder1.ToString();
    }

    ///
    /// Gets the working directory or returns null if an empty string was found.
    ///
    ///
    private string GetWorkingDirectory()
    {
        return (StartInfo.WorkingDirectory != string.Empty) ? StartInfo.WorkingDirectory : null;
    }

    ///
    /// A clone of Process.CreatePipe. This is only implemented because reflection with
    /// out parameters are a pain.
    /// Note: This is only finished for w2k and higher machines.
    ///
    ///
    ///
    /// Specifies whether the parent will be performing the writes.
    public static void MyCreatePipe(out IntPtr parentHandle, out IntPtr childHandle, bool parentInputs)
    {
        string pipename = @"\\.\pipe\Global\" + Guid.NewGuid().ToString();

        SecurityAttributes attributes2 = new SecurityAttributes();
        attributes2.bInheritHandle = false;

        parentHandle = CreateNamedPipe(pipename, 0x40000003, 0, 0xff, 0x1000, 0x1000, 0, attributes2);
        if (parentHandle == INVALID_HANDLE_VALUE)
        {
            throw new Win32Exception();
        }

        SecurityAttributes attributes3 = new SecurityAttributes();
        attributes3.bInheritHandle = true;
        int num1 = 0x40000000;
        if (parentInputs)
        {
            num1 = -2147483648;
        }
        childHandle = CreateFile(pipename, num1, 3, attributes3, 3, 0x40000080, NullHandleRef);
        if (childHandle == INVALID_HANDLE_VALUE)
        {
            throw new Win32Exception();
        }
    }
}
0
Comment
Question by:dynamicrevolutions
  • 3
3 Comments
 
LVL 5

Accepted Solution

by:
DEEPESH earned 2000 total points
ID: 17848816
Explaining whole code is bit difficult but I may help you a bit

using System;
using syntax in C# is Imports keyword in Vb.Net

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] this is the way in C# to use Windows Api
In vb.net you can use it in the following manner

<DllImport("KERNEL32.DLL", EntryPoint:="GetSystemDirectoryW", _
       SetLastError:=True, CharSet:=CharSet.Unicode, _
       ExactSpelling:=True, _
       CallingConvention:=CallingConvention.StdCall)> _
       Public Shared Function GetSystemDirectory(ByVal Buffer _
         As StringBuilder, ByVal Size As Integer) As Long
        ' Leave function empty - DLLImport attribute
        ' forces calls to GetSystemDirectory to
        ' be forwarded to GetSystemDirectory in KERNEL32.DLL
    End Function

Variable declaration in C#
SecurityAttributes attributes2 = new SecurityAttributes();
in vb.Net u can use it in following manner
Dim attributes2 as new SecurityAttributes();


In last but not least, why dont you make this code as C# assembly and
use this assembly in VB.net directly by calling methods
0
 
LVL 5

Expert Comment

by:DEEPESH
ID: 17848846
0
 
LVL 5

Expert Comment

by:DEEPESH
ID: 17848851
Sorry i forget to mention , try this one also http://www.kamalpatel.net/ConvertCSharp2VB.aspx
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Suggested Courses

927 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question