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);
		}
	}
}