1

My objective is to copy a folder from my system to a remote computer in c#. I searched everywhere and found some information on how to do that. I am calling the LogonUser function with the domain, username and password, but it it fails and returns 0.

below is my piece of code. Can you please help me figure out the problem?

class Program
{
    #region Assembly Functions
    [DllImport("advapi32.dll")]
    public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword,
        int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

    [DllImport("kernel32.dll")]
    public static extern bool CloseHandle(IntPtr handle);
    #endregion

    static void Main(string[] args)
    {
        SafeTokenHandle safeTokenHandle;
        WindowsImpersonationContext impersonatedUser = null;
        WindowsIdentity newId;
        IntPtr tokenHandle;
        IntPtr userHandle = IntPtr.Zero;
        tokenHandle = IntPtr.Zero;

        Console.WriteLine("Enter your domain.");
        string domain = Console.ReadLine();
        Console.WriteLine("Enter you user name.");
        string uname = Console.ReadLine();
        Console.WriteLine("Enter your password (Caution, password won't be hidden).");
        string password = Console.ReadLine();

        const int LOGON32_PROVIDER_DEFAULT = 0;
        //This parameter causes LogonUser to create a primary token. 
        const int LOGON32_LOGON_INTERACTIVE = 2;
        bool logon = LogonUser(uname, domain, password,
            LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle);            

        if (false == logon)
        {
            int ret = Marshal.GetLastWin32Error();
            Console.WriteLine("LogonUser failed with error code : {0}", ret);
            throw new System.ComponentModel.Win32Exception(ret);
        }

        if (logon)
        {
            newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
            using (impersonatedUser = newId.Impersonate())
            {
                // Check the identity.
                Console.WriteLine("After impersonation: "
                    + WindowsIdentity.GetCurrent().Name);
            }
            File.Copy(@"c:\result.xml", @"C:\result.xml", true);
        }

        //Undo impersonation
        if (impersonatedUser != null)
        {
            impersonatedUser.Undo();
        }

        if (tokenHandle != IntPtr.Zero)
        {
            CloseHandle(tokenHandle);
        }
    }
}



public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    private SafeTokenHandle()
        : base(true)
    {
    }

    [DllImport("kernel32.dll")]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    [SuppressUnmanagedCodeSecurity]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle(IntPtr handle);

    protected override bool ReleaseHandle()
    {
        return CloseHandle(handle);
    }
}
Julien Lebosquain
  • 40,639
  • 8
  • 105
  • 117
Vijay Nag
  • 257
  • 2
  • 9
  • 21
  • 1
    Hello, LastError 0 means success - http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx. I think the issue in this case is blocked account, wrong password, or similar thing, but code should be OK. – Ondra Oct 10 '12 at 14:40
  • 3
    You should use `[DllImport("advapi32.dll", SetLastError = true)]` to get `Marshal.GetLastWin32Error` work properly. By default, `SetLastError` is false. So please update your code and let us know the results. – Nick Hill Oct 10 '12 at 15:05

1 Answers1

-2

Why not use "Windows API Code Pack 1.1" which shows (among other things) how to use the shell to do e.g. drag and drop - which is what you essentially try to do.

If using the Shell, you don't have to think about how to logon and 1000 other things needed to support various situations.

Download the "Windows API Code Pack 1.1" package and look for DragAndDropWindow sample or some of the other samples.