I'm trying to use Process.Start() under Impersonation, i have google for few days, most answer i come across was under ASP.net, but I'm developing for Window Application, so I'm having difficulty to find the root cause.
This is my impersonate code
private void impersonateValidUser(string userName, string domain, string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if ( LogonUser( userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 )
{
tempWindowsIdentity = new WindowsIdentity( tokenDuplicate );
mImpersonationContext = tempWindowsIdentity.Impersonate();
}
}
}
and i'm trying to open document through my program (none .exe, such as .txt, .doc)
using (new Impersonator(DomainUserID, Domain, Password))
Process.Start(filePath);
So far I'm able to detect the directory/file with the impersonate user, which suppose to be invisible to my current login user since i did not grant it the access. But whenever i try to open the document, i get error
System.ComponentModel.Win32Exception (0x80004005): Access is denied
Please correct me if I'm wrong, so in this scenario, I'm not suppose to set the UseShellExecute to false (and processStartInfo with username and password input too?) because it's for executable file(?), and i do come across with CreateProcessAsUser function as well, and this function doesn't seems to be applicable to my case too, from the example i read it's for the .exe file too.
Would be appreciate if anyone could enlightenment me.
update: impersonate class
public class Impersonator : IDisposable
{
#region P/Invoke
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int LogonUser( string lpszUserName,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int DuplicateToken( IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
#endregion
#region Constants
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
#endregion
#region Attributes
private WindowsImpersonationContext mImpersonationContext = null;
#endregion
#region Public methods.
public Impersonator( string userName, string domainName, string password)
{
impersonateValidUser(userName, domainName, password);
}
#endregion
#region IDisposable member.
public void Dispose()
{
undoImpersonation();
}
#endregion
#region Private member.
private void impersonateValidUser(string userName, string domain, string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
try
{
if ( RevertToSelf() )
{
if ( LogonUser( userName, domain, password,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 )
{
tempWindowsIdentity = new WindowsIdentity( tokenDuplicate );
mImpersonationContext = tempWindowsIdentity.Impersonate();
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
finally
{
if ( token != IntPtr.Zero )
{
CloseHandle( token );
}
if ( tokenDuplicate != IntPtr.Zero )
{
CloseHandle( tokenDuplicate );
}
}
}
/// <summary>
/// Reverts the impersonation.
/// </summary>
private void undoImpersonation()
{
if ( mImpersonationContext != null )
{
mImpersonationContext.Undo();
}
}
#endregion
}