Re: Calling LogonUser() and CreateProcessAsUser() from a service

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: C Kindel (charlie_at_kindel.com)
Date: 02/08/04


Date: Sun, 8 Feb 2004 12:46:58 -0800

Thanks for the help. However, I get the same exact result using your method
(CreateProcessWithLogonW) as with my method (LogonUser/CreateProcessAsUser).
Thus it is something else. I am suspecting that it has to do with the DACLs
on the interactive desktop. This stuff confuses me greatly and I need to
ponder and read up to grok it. Hopefully someone can short-cut this for me
and just give me the code in C# that does what the code in this KB article
does...as that seems to be the right thing:

http://support.microsoft.com/default.aspx?scid=kb;[LN];Q165194

-cek

"Alireza Haghshenass" <alirezahk@hotmail.com> wrote in message
news:OHhWz8m7DHA.3432@TK2MSFTNGP11.phx.gbl...
> Hi,
> I give you a tip on doing the right way (more appropriate way) you can use
> this:
> //dwLogonFlags Specifies the logon option
>
> const int LOGON_WITH_PROFILE = 1;
>
> const int LOGON_NETCREDENTIALS_ONLY = 2;
>
> //dwCreationFlags - Specifies how the process is created
>
> const int CREATE_SUSPENDED = 0x00000004;
>
> const int CREATE_NEW_CONSOLE = 0x00000010;
>
> const int CREATE_NEW_PROCESS_GROUP = 0x00000200;
>
> const int CREATE_SEPARATE_WOW_VDM = 0x00000800;
>
> const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
>
> const int CREATE_DEFAULT_ERROR_MODE = 0x04000000;
>
> //dwCreationFlags parameter controls the new process's priority class
>
> const int NORMAL_PRIORITY_CLASS = 0x00000020;
>
> const int IDLE_PRIORITY_CLASS = 0x00000040;
>
> const int HIGH_PRIORITY_CLASS = 0x00000080;
>
> const int REALTIME_PRIORITY_CLASS = 0x00000100;
>
> const int BELOW_NORMAL_PRIORITY_CLASS = 0x00004000;
>
> const int ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000;
>
> //dwFlags
>
> // This is a bit field that determines whether certain STARTUPINFO
>
> // members are used when the process creates a window.
>
> // Any combination of the following values can be specified:
>
> const int STARTF_USESHOWWINDOW = 0x0000000;
>
> const int STARTF_USESIZE = 0x00000002;
>
> const int STARTF_USEPOSITION = 0x00000004;
>
> const int STARTF_USECOUNTCHARS = 0x00000008;
>
> const int STARTF_USEFILLATTRIBUTE = 0x00000010;
>
> const int STARTF_FORCEONFEEDBACK = 0x00000040;
>
> const int STARTF_FORCEOFFFEEDBACK = 0x00000080;
>
> const int STARTF_USESTDHANDLES = 0x00000100;
>
> const int STARTF_USEHOTKEY = 0x00000200;
>
> [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
>
> internal static extern bool CreateProcessWithLogonW(String lpszUsername,
> String lpszDomain, String lpszPassword,
>
> int dwLogonFlags, string applicationName, StringBuilder commandLine,
>
> int creationFlags, IntPtr environment,
>
> string currentDirectory,
>
> ref STARTUPINFO sui,
>
> out PROCESS_INFORMATION processInfo);
>
> [StructLayout(LayoutKind.Sequential)]
>
> internal struct STARTUPINFO
>
> {
>
> internal int cb;
>
> [MarshalAs(UnmanagedType.LPTStr)]
>
> internal string lpReserved;
>
> [MarshalAs(UnmanagedType.LPTStr)]
>
> internal string lpDesktop;
>
> [MarshalAs(UnmanagedType.LPTStr)]
>
> internal string lpTitle;
>
> internal int dwX;
>
> internal int dwY;
>
> internal int dwXSize;
>
> internal int dwYSize;
>
> internal int dwXCountChars;
>
> internal int dwYCountChars;
>
> internal int dwFillAttribute;
>
> internal int dwFlags;
>
> internal short wShowWindow;
>
> internal short cbReserved2;
>
> internal IntPtr lpReserved2;
>
> internal IntPtr hStdInput;
>
> internal IntPtr hStdOutput;
>
> internal IntPtr hStdError;
>
> }
>
> [StructLayout(LayoutKind.Sequential)]
>
> internal struct PROCESS_INFORMATION
>
> {
>
> internal IntPtr hProcess;
>
> internal IntPtr hThread;
>
> internal int dwProcessId;
>
> internal int dwThreadId;
>
> }
>
> public bool CreateProcessAs(string DomainName,string Username,string
> Password,string ProgramPath,string Params)
>
> {
>
> StringBuilder _CommandLine = new StringBuilder();
>
> if (Params.Length != 0)
>
> {
>
> _CommandLine.Append(ProgramPath + " " + Params);
>
> }
>
> else
>
> {
>
> _CommandLine.Append(ProgramPath);
>
> }
>
> PROCESS_INFORMATION _ProcessInfo;
>
> STARTUPINFO _StartInfo = new STARTUPINFO();
>
> _StartInfo.cb = Marshal.SizeOf(_StartInfo);
>
> _StartInfo.lpTitle = "Pretender Process Creator";
>
> _StartInfo.dwFlags = STARTF_USECOUNTCHARS;
>
> _StartInfo.dwYCountChars = 50;
>
> return
>
>
CreateProcessWithLogonW(Username,DomainName,Password,LOGON_WITH_PROFILE,null
> ,_CommandLine,NORMAL_PRIORITY_CLASS
> |CREATE_UNICODE_ENVIRONMENT,IntPtr.Zero,_ProgramPath,ref _StartInfo,out
> _ProcessInfo);
>
> }
>
> I wish this works right for you.
>
> "C Kindel" <charlie@kindel.com> wrote in message
> news:OzFDdRj7DHA.696@tk2msftngp13.phx.gbl...
> > I am writing a Service (in C#) that can lanuch processes in the
> interactive
> > desktop of the currently logged on user. I almost have it working, but
> even
> > after reading all the results of a gazillion google searches I'm still
> > stumped. Hopefully someone can point out what I'm doing wrong.
> >
> > If the process to be launched is "c:\windows\system32\notepad.exe" I see
> the
> > outline of Notepad appear and my service faults with a
> > "ExecutionEngineException" exception (caught by the CLR JIT debugger). I
> can
> > find no additional information on what is causing this exception. Task
> > Manager shows notepad.exe as a started service, running under the
correct
> > account. I have to kill notepad.exe with Task Manager to get the outline
> of
> > the Notepad window to go away.
> >
> > So it's sorta working, but not completely!
> >
> > I'm a newbie at using Platform Invoke in C# and it's entirely possible
> I've
> > setup marshalling info incorrectly. I also could be missing an important
> > step in the calling of LogonUser() and CreateProcessesAsUser()...
> >
> > Here's the code that does the work for me:
> >
> > public class ProcessCommands : Command
> > {
> > private String File;
> >
> > // PlatformInvoke Stuff
> > [StructLayout(LayoutKind.Sequential)]
> > struct STARTUPINFO
> > {
> > public Int32 cb;
> > [MarshalAs(UnmanagedType.LPTStr)]
> > public String lpReserved;
> > [MarshalAs(UnmanagedType.LPTStr)]
> > public String lpDesktop;
> > [MarshalAs(UnmanagedType.LPTStr)]
> > public String lpTitle;
> > public UInt32 dwX;
> > public UInt32 dwY;
> > public UInt32 dwXSize;
> > public UInt32 dwYSize;
> > public UInt32 dwXCountChars;
> > public UInt32 dwYCountChars;
> > public UInt32 dwFillAttribute;
> > public UInt32 dwFlags;
> > public Int16 wShowWindow;
> > public Int16 cbReserved2;
> > public IntPtr lpReserved2;
> > public HandleRef hStdInput;
> > public HandleRef hStdOutput;
> > public HandleRef hStdError;
> > }
> >
> > const int NORMAL_PRIORITY_CLASS = 0x00000020;
> >
> > struct PROCESS_INFORMATION
> > {
> > public HandleRef hProcess;
> > public HandleRef hThread;
> > public UInt32 dwProcessId;
> > public UInt32 dwThreadId;
> > }
> >
> > struct SECURITY_ATTRIBUTES
> > {
> > public UInt32 nLength;
> > public IntPtr lpSecurityDescriptor;
> > public Boolean bInheritHandle;
> > }
> >
> > [DllImport("advapi32.dll",CharSet=CharSet.Unicode)]
> > static extern Boolean CreateProcessAsUser(
> > IntPtr hToken,
> > String lpApplicationName,
> > String lpCommandLine,
> > IntPtr lpProcessAttributes,
> > IntPtr lpThreadAttributes,
> > Boolean bInheritHandles,
> > UInt32 dwCreationFlags,
> > IntPtr lpEnvironment,
> > String lpCurrentDirectory,
> > ref STARTUPINFO lpStartupInfo,
> > out PROCESS_INFORMATION lpProcessInformation);
> >
> > [DllImport("advapi32.dll",CharSet=CharSet.Unicode)]
> > static extern Boolean LogonUser(
> > String lpszUsername,
> > String lpszDomain,
> > String lpszPassword,
> > Int32 dwLogonType,
> > Int32 dwLogonProvider,
> > ref IntPtr phToken
> > );
> > const int LOGON32_LOGON_INTERACTIVE = 2;
> >
> > public ProcessCommands(String File)
> > {
> > this.File = File;
> > }
> >
> > public override void Execute()
> > {
> > try
> > {
> > unsafe
> > {
> > PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
> >
> > STARTUPINFO si = new STARTUPINFO();
> > si.cb = Marshal.SizeOf(si);
> > si.lpDesktop = "winsta0\\default";
> >
> > IntPtr hToken = new IntPtr(0);
> > if (LogonUser("auser", "mydomain", "Passw0rd!",
> > LOGON32_LOGON_INTERACTIVE, 0, ref hToken))
> > {
> > Boolean bResult = CreateProcessAsUser(
> > hToken,
> > File, // file to execute
> > null, // command line
> > IntPtr.Zero, // pointer to process
SECURITY_ATTRIBUTES
> > IntPtr.Zero, // pointer to thread
SECURITY_ATTRIBUTES
> > false, // handles are not inheritable
> > 0, // creation flags
> > IntPtr.Zero, // pointer to new environment block
> > null, // name of current directory
> > ref si, // pointer to STARTUPINFO structure
> > out pi // receives information about new process
> > );
> >
> > if (bResult)
> > {
> > ...
> > }
> > }
> > }
> >
> > }
> > catch(Exception e)
> > {
> > ...
> > }
> > }
> >
> > }
> >
> >
>
>



Relevant Pages