tags:

views:

173

answers:

2

I am trying to move a file, but gives this error:

System.UnauthorizedAccessException: Access to the path is denied..
at System.IO._Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.
_Error.WinIOError()
at System.IO.FileInfo.MoveTo(String destFileName)

To move the file, I have this code:

public void MssFile_Move (string ssPath, string ssDestinationDirectoryPath, string ssDomain, string ssUsername, string ssPassword, out string ssError_message) {
        IntPtr admin_token = IntPtr.Zero;
        ssError_message = "";

        try
        {
            DoImpersonateLoggedOnUser(  ssDomain
                          , ssUsername
                          , ssPassword
                          , out ssError_message
                          , out admin_token);                   


            FileInfo fi = new FileInfo(ssPath);
            //Destination Directory does not exist ?
            if ( !Directory.Exists(Path.GetDirectoryName(ssDestinationDirectoryPath)))
                    Directory.CreateDirectory(Path.GetDirectoryName(
                    ssDestinationDirectoryPath));
            fi.MoveTo (ssDestinationDirectoryPath);

            DoRevertToSelf(ssDomain);

        }
        catch (System.Exception se)
        {
            int ret = Marshal.GetLastWin32Error();
            ssError_message += "Win32Error: " + ret + "\n";
            ssError_message += se.ToString();
        }
        finally
        {
            if (admin_token != IntPtr.Zero)
                CloseHandle(admin_token);
        }                   
    }

To impersonate I have:

[DllImport("advapi32.DLL", SetLastError = true)]
        public static extern int LogonUser(string lpszUsername, string lpszDomain,
            string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
        [DllImport("advapi32.DLL")]
        public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); //handle to token for logged-on user


public void DoImpersonateLoggedOnUser (     string ssDomain
                                            ,   string ssUsername
                                            ,   string ssPassword
                                            ,   out string ssError_message
                                            ,   out IntPtr admin_token)
    {
        IntPtr phToken = IntPtr.Zero;
        admin_token = IntPtr.Zero;
        ssError_message = "";

        if (ssDomain != "")
        {
            if (LogonUser(ssUsername, ssDomain, ssPassword, 9, 0, out phToken) != 0)
            {
                ImpersonateLoggedOnUser(phToken);           
            }
            else
            {
                int nErrorCode = Marshal.GetLastWin32Error();

                ssError_message = "Operation Failed, error: " + nErrorCode;
            }
            admin_token = phToken;
        }           
    }

If I set the folder /file to permissions everyone, it works, but I don't want that. What am I doing wrong?

A: 

there are two possible conflicts: is the impersonated use allowed to delete the source-file ?

is the user allowed to see the full path down to ssDestinationDirectoryPath ?

I've got much trouble with file-moves, so please try to copy and then delete.

ralf.w.
Copy work ok, but when i go delete, gives me this error: System.UnauthorizedAccessException: Access to the path 'C:\test.txt' is denied
Luis
so, using LogonProvider.WinNT50 and LogonType.Interactive did the trick... btw I have not ever found LogonType == 0.
ralf.w.
A: 

Done it sucessfull with this code.

    [DllImport("advapi32.DLL", SetLastError = true)]
        public static extern int LogonUser(string lpszUsername, string lpszDomain,
            string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
        [DllImport("advapi32.DLL")]
        public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); //handle to token for logged-on user
        [DllImport("advapi32.DLL")]
        public static extern bool RevertToSelf();
        [DllImport("kernel32.dll")]
        public extern static bool CloseHandle(IntPtr hToken);

        enum LogonType
        {
            Interactive = 2,
            Network = 3,
            Batch = 4,
            Service = 5,
            Unlock = 7,
            NetworkClearText = 8,
            NewCredentials = 9
        }

        enum LogonProvider
        {
            Default = 0,
            WinNT35 = 1,
            WinNT40 = 2,
            WinNT50 = 3
        }

int valid = LogonUser(ssUsername,
                            ssDomain,
                            ssPassword,
                            (int)LogonType.Interactive,
                            (int)LogonProvider.WinNT50,
                            out admin_token);
                if (valid != 0)
                {
                    using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(admin_token))
                    {
                        CloseHandle(admin_token);
                        FileInfo fi = new FileInfo(ssPath);
                        //Destination Directory does not exist ?
                        if (!Directory.Exists(Path.GetDirectoryName(ssDestinationDirectoryPath)))
                            Directory.CreateDirectory(Path.GetDirectoryName(
                            ssDestinationDirectoryPath));
                        fi.CopyTo(ssDestinationDirectoryPath);
                        fi.Delete();
                    }
                }
Luis