In my ASP.NET Application, I must access file share on a remote server by its UNC path, i.e., \\server\folder\subfolder\, using specific username and password.
using System; using System.Runtime.InteropServices; using System.Security.Principal; using System.IO; namespace RemoteCredentials { class MainClass { [DllImport( "advapi32.dll", SetLastError = true )] private static extern bool LogonUser( string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken ); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr *arguments); [DllImport( "kernel32.dll", CharSet = CharSet.Auto, SetLastError = true )] private static extern bool CloseHandle( IntPtr handle); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public extern static bool DuplicateToken( IntPtr existingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr duplicateTokenHandle ); // logon types const int LOGON32_LOGON_INTERACTIVE = 2; const int LOGON32_LOGON_NETWORK = 3; const int LOGON32_LOGON_NEW_CREDENTIALS = 9; // logon providers const int LOGON32_PROVIDER_DEFAULT = 0; const int LOGON32_PROVIDER_WINNT50 = 3; const int LOGON32_PROVIDER_WINNT40 = 2; const int LOGON32_PROVIDER_WINNT35 = 1; ////// The main entry point for the application. /// [STAThread] static void Main(string[] args) { IntPtr token = IntPtr.Zero; IntPtr dupToken = IntPtr.Zero; bool isSuccess = LogonUser( "userId", "192.168.1.1", "password", LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref token ); if( !isSuccess ) { RaiseLastError(); } isSuccess = DuplicateToken( token, 2, ref dupToken ); if( !isSuccess ) { RaiseLastError(); } WindowsIdentity newIdentity = new WindowsIdentity( dupToken ); WindowsImpersonationContext impersonatedUser = newIdentity.Impersonate(); DirectoryInfo dirInfo = new DirectoryInfo( @"\\192.19.12.46\sharedfolder" ); FileInfo[] files = dirInfo.GetFiles(); impersonatedUser.Undo(); foreach( FileInfo file in files ) { Console.WriteLine( file.FullName ); } isSuccess = CloseHandle( token ); if( !isSuccess ) { RaiseLastError(); } } // GetErrorMessage formats and returns an error message // corresponding to the input errorCode. public unsafe static string GetErrorMessage( int errorCode ) { int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; int messageSize = 255; string lpMsgBuf = ""; int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; IntPtr ptrlpSource = IntPtr.Zero; IntPtr ptrArguments = IntPtr.Zero; int retVal = FormatMessage( dwFlags, ref ptrlpSource, errorCode, 0, ref lpMsgBuf, messageSize, &ptrArguments); if( retVal == 0 ) { throw new ApplicationException( string.Format( "Failed to format message for error code '{0}'." , errorCode ) ); } return lpMsgBuf; } private static void RaiseLastError() { int errorCode = Marshal.GetLastWin32Error(); string errorMessage = GetErrorMessage(errorCode ); throw new ApplicationException( errorMessage); } } }