I'm attempting to logon to a computer remotely so that I can copy a local directory locally. I'm attempting to use the LogonUser function call found in the advapi32 DLL. When I call the function, it returns 0 (false) but when I call Marshal.GetLastWin32Error() that also returns 0, indicating that there was no error. The username and password I'm trying to use I know works because I use it to log on to the computer. I've used both domain and local accounts and both return the same result. Below is my attempt to logon to the computer.
[DllImport("advapi32.DLL", SetLastError = true)]
public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLongonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.Dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[DllImport("kernel32.DLL", CharSet = CharSet.Auto)]
public static extern string GetLastError();
private static void CopyDirectory(string computerName, string localPath, string remotePath)
{
WindowsImpersonationContext impersonationContext = null;
IntPtr userHandle = IntPtr.Zero;
string username = @"testing";
string password = @"testing";
string fullRemotePath = string.Format("{0}\\{1}", computerName, remotePath);
try
{
bool Logon = LogonUser(username, computerName, password, 2, 0, ref userHandle);
if (!Logon)
{
Console.WriteLine("Error Logging in");
int errorCode = Marshal.GetLastWin32Error();
Console.WriteLine(string.Format("Error Code: {0}", errorCode));
Console.WriteLine(new Win32Exception(errorCode).Message);
}
else
{
WindowsIdentity user = new WindowsIdentity(userHandle);
impersonationContext = user.Impersonate();
System.IO.File.Copy(localPath, fullRemotePath, true);
}
}
catch (Exception ex)
{
int errorCode = Marshal.GetLastWin32Error();
Console.WriteLine(string.Format("Error Code: {0}", errorCode));
Console.WriteLine(ex.Message);
}
finally
{
if(impersonationContext != null)
impersonationContext.Undo();
if(userHandle != IntPtr.Zero)
CloseHandle(userHandle);
}
}
Could you please assist me in finding my flaw?
EDIT: I found the following comment here
Even if an API supports SetLastError/GetLastError, the value returned by GetLastError is only meaningful if the API you just called actually fails. How that failure is indicated depends on the API. Except for a couple of braindead API/situation combinations, like Impersonate* with the new SeImpersonatePrivilege: the API can return a success code even if it fails due to lack of privilege, leaving you with only an identification token. Then you have to call GetLastError () to find out why the nominally-successful API call failed....
I have a feeling this is what is causing me problems. How do I get around this?