diff -Nur source/FzSFtp/psftp.c source.patch/FzSFtp/psftp.c
--- source/FzSFtp/psftp.c	Mon Mar 14 16:16:12 2005
+++ source.patch/FzSFtp/psftp.c	Tue Mar 15 11:37:15 2005
@@ -17,6 +17,7 @@
 #include "int64.h"
 
 #include "FzSFtpIpc.h"
+#include <tchar.h>
 
 /*
  * Since SFTP is a request-response oriented protocol, it requires
@@ -389,12 +390,37 @@
 	sfree(fname);
 	return 0;
     }
-
+#ifdef _UNICODE
+	{
+		int len;
+
+		// convert from UTF-8 to ANSI
+		len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)outfname, -1, NULL, 0);
+		if (len != 0)
+		{
+			wchar_t *p1;
+
+			p1 = malloc(sizeof(wchar_t) * (len*2+1));
+			MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)outfname, -1 , (LPWSTR)p1, len*2);
+			if (restart)
+			fp = CreateFile(p1, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+			else
+			fp = CreateFile(p1, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
+			free(p1);
+		}
+		else {
+			if (restart)
+			fp = CreateFileA(outfname, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+			else
+			fp = CreateFileA(outfname, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
+		}
+	}
+#else
     if (restart)
 	fp = CreateFileA(outfname, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
     else
 	fp = CreateFileA(outfname, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
-
+#endif
     if (fp==INVALID_HANDLE_VALUE)
     {
 	FzSFtpIpc_Error1("Unable to open %s", outfname);
@@ -508,7 +534,28 @@
 	return 0;
     }
 
+#ifdef _UNICODE
+	{
+		int len;
+
+		// convert from UTF-8 to ANSI
+		len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)localfile, -1, NULL, 0);
+		if (len != 0)
+		{
+			wchar_t *p1;
+
+			p1 = malloc(sizeof(wchar_t) * (len*2+1));
+			MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)localfile, -1 , (LPWSTR)p1, len*2);
+		    fp = CreateFile(p1, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+			free(p1);
+		}
+		else {
+		    fp = CreateFileA(localfile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+		}
+	}
+#else
     fp = CreateFileA(localfile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+#endif
     if (fp == INVALID_HANDLE_VALUE)
     {
 	FzSFtpIpc_Error1("Unable to open %s", localfile);
diff -Nur source/SFtpIpc.cpp source.patch/SFtpIpc.cpp
--- source/SFtpIpc.cpp	Wed Oct 27 16:01:46 2004
+++ source.patch/SFtpIpc.cpp	Tue Mar 15 11:43:00 2005
@@ -146,6 +146,7 @@
 
 	m_hReceiveThread=0;
 	m_hExitEvent=0;
+	m_bUTF8 = pOwner->m_bUTF8;
 }
 
 CSFtpIpc::~CSFtpIpc()
@@ -326,7 +327,7 @@
 	return 0;
 }
 
-BOOL CSFtpIpc::Send(const DWORD &nID, const DWORD &nDataLength, const LPVOID pData)
+BOOL CSFtpIpc::Send(const DWORD &nID, const DWORD &nDataLength, const LPVOID pData, CString status)
 {
 	USES_CONVERSION;
 	ASSERT(m_hSFtpProcess);
@@ -336,38 +337,74 @@
 	ASSERT(!nDataLength || pData);
 
 	CString str;
-	if (nID==SFTP_DATAID_STC_CONNECT)
-		str.Format( _T("CONNECT %s@%s:%d"), A2CT((char *)pData+strlen((char *)pData)+1+4), A2CT((char *)pData), *(int *)((char *)pData+strlen((char *)pData)+1) );
+	if (nID==SFTP_DATAID_STC_CONNECT) {
+		if (status == "")
+			str.Format( _T("CONNECT %s@%s:%d"), A2CT((char *)pData+strlen((char *)pData)+1+4), A2CT((char *)pData), *(int *)((char *)pData+strlen((char *)pData)+1) );
+		else
+			str = _T("CONNECT ") + status;
+	}
 	else if (nID==SFTP_DATAID_STC_PWD)
 		str="PWD";
-	else if (nID==SFTP_DATAID_STC_CD)
-		str=(CString)"CD " + (char *)pData;
+	else if (nID==SFTP_DATAID_STC_CD) {
+		if (status == "")
+			str=(CString)"CD " + (char *)pData;
+		else
+			str = _T("CD ") + status;
+	}
 	else if (nID==SFTP_DATAID_STC_LIST)
 		str="LIST";
-	else if (nID==SFTP_DATAID_STC_MKD)
-		str=(CString)"MKD " + (char *)pData;
-	else if (nID==SFTP_DATAID_STC_GET)
-		str.Format( _T("GET %s %s %s"), 
+	else if (nID==SFTP_DATAID_STC_MKD) {
+		if (status == "")
+			str=(CString)"MKD " + (char *)pData;
+		else
+			str = _T("MKD ") + status;
+	}
+	else if (nID==SFTP_DATAID_STC_GET) {
+		if (status == "")
+			str.Format( _T("GET %s %s %s"), 
 					A2CT((char *)pData), 
 					A2CT((char *)pData+strlen((char *)pData)+1), 
 					( *(int *)((char *)pData+strlen((char *)pData)+1+strlen((char *)pData+strlen((char *)pData)+1)+1)?_T("TRUE"):_T("FALSE") ));
-	else if (nID==SFTP_DATAID_STC_PUT)
-		str.Format( _T("PUT %s %s %s"), 
+		else
+			str = _T("GET ") + status;
+	}
+	else if (nID==SFTP_DATAID_STC_PUT) {
+		if (status == "")
+			str.Format( _T("PUT %s %s %s"), 
 					A2CT((char *)pData), 
 					A2CT((char *)pData+strlen((char *)pData)+1), 
 					( *(int *)((char *)pData+strlen((char *)pData)+1+strlen((char *)pData+strlen((char *)pData)+1)+1)?_T("TRUE"):_T("FALSE") ));
-	else if (nID==SFTP_DATAID_STC_DELE)
-		str=(CString)"DELE " + (char *)pData;
-	else if (nID==SFTP_DATAID_STC_RMD)
-		str=(CString)"RMD " + (char *)pData;
-	else if (nID==SFTP_DATAID_STC_RENAME)
-		str.Format( _T("RENAME %s %s"), 
+		else
+			str = _T("PUT ") + status;
+	}
+	else if (nID==SFTP_DATAID_STC_DELE) {
+		if (status == "")
+			str=(CString)"DELE " + (char *)pData;
+		else
+			str = _T("DELE ") + status;
+	}
+	else if (nID==SFTP_DATAID_STC_RMD) {
+		if (status == "")
+			str=(CString)"RMD " + (char *)pData;
+		else
+			str = _T("RMD ") + status;
+	}
+	else if (nID==SFTP_DATAID_STC_RENAME) {
+		if (status == "")
+			str.Format( _T("RENAME %s %s"), 
 					A2CT((char *)pData), 
 					A2CT((char *)pData+strlen((char *)pData)+1));
-	else if (nID==SFTP_DATAID_STC_CHMOD)
-		str.Format( _T("CHMOD %s %s"), 
+		else
+			str = _T("RENAME ") + status;
+	}
+	else if (nID==SFTP_DATAID_STC_CHMOD) {
+		if (status == "")
+			str.Format( _T("CHMOD %s %s"), 
 					A2CT((char *)pData), 
 					A2CT((char *)pData+strlen((char *)pData)+1));
+		else
+			str = _T("CHMOD ") + status;
+	}
 	if (str!="")
 		m_pOwner->ShowStatus(str, 2);
 		
@@ -417,8 +454,25 @@
 BOOL CSFtpIpc::Send(const DWORD &nID, LPCTSTR str)
 {
 	USES_CONVERSION;
-	if (str)
-		return Send(nID, (const DWORD)strlen(T2CA(str))+1, (LPVOID)T2CA(str));
+
+	if (str) {
+		if (m_bUTF8)
+		{
+			bool res;
+			LPCWSTR unicode = T2CW(str);
+			int len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, 0, 0, 0, 0);
+			char* utf8 = new char[len + 1];
+			WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf8, len + 1, 0, 0);
+
+			res = Send(nID, (const DWORD)strlen(utf8)+1, (LPVOID)utf8, str);
+			delete [] utf8;
+			return res;
+		}
+		else
+		{
+			return Send(nID, (const DWORD)strlen(T2CA(str))+1, (LPVOID)T2CA(str), str);
+		}
+	}
 	else
 		return Send(nID, 0, 0);
 }
diff -Nur source/SFtpIpc.h source.patch/SFtpIpc.h
--- source/SFtpIpc.h	Mon Jun  7 22:59:16 2004
+++ source.patch/SFtpIpc.h	Tue Mar 15 11:37:15 2005
@@ -34,7 +34,7 @@
 	friend CSFtpIpcHelperWindow;
 public:
 	BOOL Send(const DWORD &nID, LPCTSTR str);
-	BOOL Send(const DWORD &nID, const DWORD &nDataLength, const LPVOID pData);
+	BOOL Send(const DWORD &nID, const DWORD &nDataLength, const LPVOID pData, CString status = "");
 	BOOL AttachProcess(HANDLE hSFtpProcess);
 	CString GetHandleString();
 	CSFtpIpc(CSFtpControlSocket *pOwner);
@@ -64,6 +64,7 @@
 	HANDLE m_hReceiveThread;
 	static DWORD WINAPI ReceiveThread( LPVOID pParam );
 	HANDLE m_hExitEvent;
+	bool m_bUTF8;
 };
 
 #endif // !defined(AFX_SFTPIPC_H__71B20B86_C3D8_4197_90C2_349A18548D58__INCLUDED_)
diff -Nur source/SftpControlSocket.cpp source.patch/SftpControlSocket.cpp
--- source/SftpControlSocket.cpp	Mon Mar 14 16:00:26 2005
+++ source.patch/SftpControlSocket.cpp	Tue Mar 15 13:20:14 2005
@@ -39,7 +39,7 @@
 class CSFtpControlSocket::CFileTransferData : public CSFtpControlSocket::t_operation::COpData
 {
 public:
-	CFileTransferData(t_server server) 
+	CFileTransferData(t_server server, bool bUTF8) 
 	{
 		pDirectoryListing=0;
 		nWaitNextOpState=0;
@@ -50,7 +50,7 @@
 		transferdata.nTransferStart=0;
 		pStartTime=0;
 		bUseAbsolutePaths = FALSE;
-		pParser = new CFtpListResult(server);
+		pParser = new CFtpListResult(server, bUTF8);
 	};
 	virtual ~CFileTransferData() 
 	{
@@ -79,10 +79,10 @@
 class CSFtpControlSocket::CListData:public CSFtpControlSocket::t_operation::COpData
 {
 public:
-	CListData(t_server server) 
+	CListData(t_server server, bool bUTF8) 
 	{
 		pDirectoryListing=0;
-		pParser = new CFtpListResult(server);
+		pParser = new CFtpListResult(server, bUTF8);
 	}
 	virtual ~CListData() 
 	{
@@ -124,6 +124,7 @@
 	m_bQuit=FALSE;
 	m_bCheckForTimeout=TRUE;
 	m_bError=FALSE;
+	m_bUTF8 = false;
 }
 
 CSFtpControlSocket::~CSFtpControlSocket()
@@ -154,7 +155,9 @@
 	ASSERT(!m_Operation.nOpMode);
 	
 	ASSERT(!m_pProxyLayer);
-	
+
+	m_bUTF8 = (server.nUTF8 == 1);
+
 	if (!server.fwbypass)
 	{
 		int nProxyType=COptions::GetOptionVal(OPTION_PROXYTYPE);
@@ -326,13 +329,41 @@
 		if (m_Operation.nOpState==LIST_PWD)
 		{ //Reply to PWD command
 			pData->realpath.SetServer(m_CurrentServer);
-			if (m_Reply=="" || !pData->realpath.SetPath(A2CT(m_Reply)))
-			{
-				LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
-				ResetOperation(FZ_REPLY_ERROR);
-				return;
+			if (m_bUTF8) {
+				USES_CONVERSION;
+
+				// convert from UTF-8 to ANSI
+				int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_Reply, -1, NULL, 0);
+				if (len != 0)
+				{
+					LPWSTR p1 = new WCHAR[len + 1];
+					MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_Reply, -1 , (LPWSTR)p1, len*2);
+					CString tempstr = W2CT(p1);
+					delete [] p1;
+					if (tempstr=="" || !pData->realpath.SetPath(tempstr))
+					{
+						LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
+						ResetOperation(FZ_REPLY_ERROR);
+						return;
+					}
+					pData->rawpwd=tempstr;
+				}
+				else
+				{
+					LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
+					ResetOperation(FZ_REPLY_ERROR);
+					return;
+				}
+			}
+			else {
+				if (m_Reply=="" || !pData->realpath.SetPath(A2CT(m_Reply)))
+				{
+					LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
+					ResetOperation(FZ_REPLY_ERROR);
+					return;
+				}
+				pData->rawpwd=m_Reply;
 			}
-			pData->rawpwd=m_Reply;
 			m_pOwner->SetCurrentPath(pData->realpath);
 			if (pData->nListMode&FZ_LIST_USECACHE)
 			{
@@ -363,13 +394,41 @@
 		else if (m_Operation.nOpState==LIST_CWD)
 		{
 			pData->realpath.SetServer(m_CurrentServer);
-			if (m_Reply == "" || !pData->realpath.SetPath(A2CT(m_Reply)))
-			{
-				LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
-				ResetOperation(FZ_REPLY_ERROR);
-				return;
+			if (m_bUTF8) {
+				USES_CONVERSION;
+
+				// convert from UTF-8 to ANSI
+				int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_Reply, -1, NULL, 0);
+				if (len != 0)
+				{
+					LPWSTR p1 = new WCHAR[len + 1];
+					MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_Reply, -1 , (LPWSTR)p1, len*2);
+					CString tempstr = W2CT(p1);
+					delete [] p1;
+					if (tempstr=="" || !pData->realpath.SetPath(tempstr))
+					{
+						LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
+						ResetOperation(FZ_REPLY_ERROR);
+						return;
+					}
+					pData->rawpwd=tempstr;
+				}
+				else
+				{
+					LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
+					ResetOperation(FZ_REPLY_ERROR);
+					return;
+				}
+			}
+			else {
+				if (m_Reply=="" || !pData->realpath.SetPath(A2CT(m_Reply)))
+				{
+					LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
+					ResetOperation(FZ_REPLY_ERROR);
+					return;
+				}
+				pData->rawpwd=m_Reply;
 			}
-			pData->rawpwd = m_Reply;
 			m_pOwner->SetCurrentPath(pData->realpath);
 			if (pData->nListMode&FZ_LIST_USECACHE && pData->subdir=="")
 			{
@@ -410,13 +469,41 @@
 		else if (m_Operation.nOpState==LIST_CWD2)
 		{
 			pData->realpath.SetServer(m_CurrentServer);
-			if (m_Reply=="" || !pData->realpath.SetPath(A2CT(m_Reply)))
-			{
-				LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
-				ResetOperation(FZ_REPLY_ERROR);
-				return;
+			if (m_bUTF8) {
+				USES_CONVERSION;
+
+				// convert from UTF-8 to ANSI
+				int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_Reply, -1, NULL, 0);
+				if (len != 0)
+				{
+					LPWSTR p1 = new WCHAR[len + 1];
+					MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_Reply, -1 , (LPWSTR)p1, len*2);
+					CString tempstr = W2CT(p1);
+					delete [] p1;
+					if (tempstr=="" || !pData->realpath.SetPath(tempstr))
+					{
+						LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
+						ResetOperation(FZ_REPLY_ERROR);
+						return;
+					}
+					pData->rawpwd=tempstr;
+				}
+				else
+				{
+					LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
+					ResetOperation(FZ_REPLY_ERROR);
+					return;
+				}
+			}
+			else {
+				if (m_Reply=="" || !pData->realpath.SetPath(A2CT(m_Reply)))
+				{
+					LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path") );
+					ResetOperation(FZ_REPLY_ERROR);
+					return;
+				}
+				pData->rawpwd=m_Reply;
 			}
-			pData->rawpwd=m_Reply;
 			m_pOwner->SetCurrentPath(pData->realpath);
 			if (pData->nListMode&FZ_LIST_USECACHE)
 			{
@@ -512,7 +599,7 @@
 	
 	if (m_Operation.nOpState==LIST_INIT)
 	{ //Initialize some variables
-		pData = new CListData(m_CurrentServer);;
+		pData = new CListData(m_CurrentServer, m_bUTF8);
 		pData->nListMode=nListMode;
 		pData->path=path;
 		pData->subdir=subdir;
@@ -691,7 +778,7 @@
 		
 		m_Operation.nOpMode=CSMODE_TRANSFER|(transferfile->get?CSMODE_DOWNLOAD:CSMODE_UPLOAD);
 
-		pData = new CFileTransferData(m_CurrentServer);
+		pData = new CFileTransferData(m_CurrentServer, m_bUTF8);
 		m_Operation.pData=pData;
 
 		//Replace invalid characters in the local filename
@@ -821,14 +908,35 @@
 			{
 				CServerPath path;
 				path.SetServer(m_CurrentServer);
-				if (!path.SetPath(A2CT(m_Reply)))
+				CString tempstr;
+				if (m_bUTF8) {
+					USES_CONVERSION;
+
+					// convert from UTF-8 to ANSI
+					int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_Reply, -1, NULL, 0);
+					if (len != 0)
+					{
+						LPWSTR p1 = new WCHAR[len + 1];
+						MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_Reply, -1 , (LPWSTR)p1, len*2);
+						tempstr = W2CT(p1);
+						delete [] p1;
+					}
+					else
+					{
+						tempstr = "";
+					}
+				}
+				else {
+					tempstr = A2CT(m_Reply);
+				}
+				if (!path.SetPath(tempstr))
 				{
 					LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path"));
 					nReplyError=FZ_REPLY_ERROR;
 				}
 				else
 				{
-					pData->rawpwd=m_Reply;
+					pData->rawpwd=tempstr;
 					m_pOwner->SetCurrentPath(path);
 					if (path!=pData->transferfile.remotepath)
 						nReplyError=FZ_REPLY_ERROR | FZ_REPLY_CRITICALERROR;
@@ -1046,14 +1154,35 @@
 			{
 				CServerPath path;
 				path.SetServer(m_CurrentServer);
-				if (!path.SetPath(A2CT(m_Reply)))
+				CString tempstr;
+				if (m_bUTF8) {
+					USES_CONVERSION;
+
+					// convert from UTF-8 to ANSI
+					int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_Reply, -1, NULL, 0);
+					if (len != 0)
+					{
+						LPWSTR p1 = new WCHAR[len + 1];
+						MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_Reply, -1 , (LPWSTR)p1, len*2);
+						tempstr = W2CT(p1);
+						delete [] p1;
+					}
+					else
+					{
+						tempstr = "";
+					}
+				}
+				else {
+					tempstr = A2CT(m_Reply);
+				}
+				if (!path.SetPath(tempstr))
 				{
 					LogMessage(__FILE__, __LINE__, this,FZ_LOG_WARNING, _T("Can't parse path"));
 					nReplyError=FZ_REPLY_ERROR;
 				}
 				else
 				{
-					pData->rawpwd=m_Reply;
+					pData->rawpwd=tempstr;
 					m_pOwner->SetCurrentPath(path);
 					if (path!=pData->transferfile.remotepath)
 						nReplyError=FZ_REPLY_ERROR | FZ_REPLY_CRITICALERROR;
@@ -1336,21 +1465,77 @@
 			filename = pData->transferfile.remotefile;
 		else
 			filename = pData->transferfile.remotepath.GetPath() + pData->transferfile.remotefile;
-		int nLen1 = strlen(T2CA(filename)) + 1;
-		int nLen2 = strlen(T2CA(pData->transferfile.localfile)) + 1;
-		char *pCmd=new char[nLen1+nLen2+4];
-		strcpy(pCmd, T2CA(filename));
-		strcpy(pCmd+nLen1, T2CA(pData->transferfile.localfile));
-		memcpy(pCmd+nLen1+nLen2, &pData->transferdata.bResume, 4);
+		char *pCmd;
+		int nLen1;
+		int nLen2;
+		CString status = filename + _T(" ") + pData->transferfile.localfile;
+		if (pData->transferdata.bResume)
+			status += _T(" TRUE");
+		else
+			status += _T(" FALSE");
+		if (m_bUTF8) {
+#ifdef _UNICODE
+			LPCWSTR unicode_remote = T2CW(filename);
+			int len = WideCharToMultiByte(CP_UTF8, 0, unicode_remote, -1, 0, 0, 0, 0);
+			char* utf8_remote = new char[len + 1];
+			WideCharToMultiByte(CP_UTF8, 0, unicode_remote, -1, utf8_remote, len + 1, 0, 0);
+			LPCWSTR unicode_local = T2CW(pData->transferfile.localfile);
+			len = WideCharToMultiByte(CP_UTF8, 0, unicode_local, -1, 0, 0, 0, 0);
+			char* utf8_local = new char[len + 1];
+			WideCharToMultiByte(CP_UTF8, 0, unicode_local, -1, utf8_local, len + 1, 0, 0);
+			nLen1=strlen(utf8_remote) + 1;
+			nLen2=strlen(utf8_local)+1;
+			pCmd=new char[nLen1+nLen2+4];
+			strcpy(pCmd, utf8_remote);
+			delete [] utf8_remote;
+			strcpy(pCmd+nLen1, utf8_local);
+			delete [] utf8_local;
+			memcpy(pCmd+nLen1+nLen2, &pData->transferdata.bResume, 4);
+#else
+			LPCWSTR unicode_remote = T2CW(filename);
+			int len = WideCharToMultiByte(CP_UTF8, 0, unicode_remote, -1, 0, 0, 0, 0);
+			char* utf8_remote = new char[len + 1];
+			WideCharToMultiByte(CP_UTF8, 0, unicode_remote, -1, utf8_remote, len + 1, 0, 0);
+			nLen1=strlen(utf8_remote) + 1;
+			nLen2=strlen(T2CA(pData->transferfile.localfile))+1;
+			pCmd=new char[nLen1+nLen2+4];
+			strcpy(pCmd, utf8_remote);
+			delete [] utf8_remote;
+			strcpy(pCmd+nLen1, T2CA(pData->transferfile.localfile));
+			memcpy(pCmd+nLen1+nLen2, &pData->transferdata.bResume, 4);
+#endif
+		}
+		else {
+#ifdef _UNICODE
+			LPCWSTR unicode_local = T2CW(pData->transferfile.localfile);
+			int len = WideCharToMultiByte(CP_UTF8, 0, unicode_local, -1, 0, 0, 0, 0);
+			char* utf8_local = new char[len + 1];
+			WideCharToMultiByte(CP_UTF8, 0, unicode_local, -1, utf8_local, len + 1, 0, 0);
+			nLen1=strlen(T2CA(filename)) + 1;
+			nLen2=strlen(utf8_local)+1;
+			pCmd=new char[nLen1+nLen2+4];
+			strcpy(pCmd, T2CA(filename));
+			strcpy(pCmd+nLen1, utf8_local);
+			delete [] utf8_local;
+			memcpy(pCmd+nLen1+nLen2, &pData->transferdata.bResume, 4);
+#else
+			nLen1=strlen(T2CA(filename)) + 1;
+			nLen2=strlen(T2CA(pData->transferfile.localfile))+1;
+			pCmd=new char[nLen1+nLen2+4];
+			strcpy(pCmd, T2CA(filename));
+			strcpy(pCmd+nLen1, T2CA(pData->transferfile.localfile));
+			memcpy(pCmd+nLen1+nLen2, &pData->transferdata.bResume, 4);
+#endif
+		}
 		pData->pStartTime = new CTime;
 		*pData->pStartTime = CTime::GetCurrentTime();
 		if (pData->transferfile.get)
 		{
-			if (!m_pDataChannel->Send(SFTP_DATAID_STC_GET, nLen1+nLen2+4, pCmd))
+			if (!m_pDataChannel->Send(SFTP_DATAID_STC_GET, nLen1+nLen2+4, pCmd, status))
 				bError=TRUE;
 		}
 		else
-			if (!m_pDataChannel->Send(SFTP_DATAID_STC_PUT, nLen1+nLen2+4, pCmd))
+			if (!m_pDataChannel->Send(SFTP_DATAID_STC_PUT, nLen1+nLen2+4, pCmd, status))
 				bError=TRUE;
 
 
@@ -1506,21 +1691,40 @@
 		m_Operation.nOpMode = CSMODE_RENAME;
 		int nLen;
 		char *pData;
+		CString s_oldname, s_newname;
 		if (newPath.IsEmpty())
 		{
-			nLen = _tcslen( path.GetPath() + oldName + path.GetPath() + newName) + 2;
+			s_oldname = path.GetPath() + oldName;
+			s_newname = path.GetPath() + newName;
+		}
+		else {
+			s_oldname = path.GetPath() + oldName;
+			s_newname = newPath.GetPath() + newName;
+		}
+		CString status = s_oldname + _T(" ") + s_newname;
+		if (m_bUTF8) {
+			LPCWSTR uni_oldname = T2CW(s_oldname);
+			int len = WideCharToMultiByte(CP_UTF8, 0, uni_oldname, -1, 0, 0, 0, 0);
+			char* utf8_oldname = new char[len + 1];
+			WideCharToMultiByte(CP_UTF8, 0, uni_oldname, -1, utf8_oldname, len + 1, 0, 0);
+			LPCWSTR uni_newname = T2CW(s_newname);
+			len = WideCharToMultiByte(CP_UTF8, 0, uni_newname, -1, 0, 0, 0, 0);
+			char* utf8_newname = new char[len + 1];
+			WideCharToMultiByte(CP_UTF8, 0, uni_newname, -1, utf8_newname, len + 1, 0, 0);
+			nLen = strlen(utf8_oldname) + strlen(utf8_newname) + 2;
 			pData = new char[nLen];
-			strcpy(pData, T2CA(path.GetPath() + oldName));
-			strcpy(pData + _tcslen(path.GetPath() + oldName) + 1, T2CA(path.GetPath() + newName));
+			strcpy(pData, utf8_oldname);
+			strcpy(pData + strlen(utf8_oldname) + 1, utf8_newname);
+			delete [] utf8_oldname;
+			delete [] utf8_newname;
 		}
-		else
-		{
-			nLen = _tcslen( path.GetPath() + oldName + newPath.GetPath() + newName) + 2;
+		else {
+			nLen = _tcslen( s_oldname + s_newname) + 2;
 			pData = new char[nLen];
-			strcpy(pData, T2CA(path.GetPath() + oldName));
-			strcpy(pData + _tcslen(path.GetPath() + oldName) + 1, T2CA(newPath.GetPath() + newName));
+			strcpy(pData, T2CA(s_oldname));
+			strcpy(pData + _tcslen(s_oldname) + 1, T2CA(s_newname));
 		}
-		if (!m_pDataChannel->Send(SFTP_DATAID_STC_RENAME, nLen, pData))
+		if (!m_pDataChannel->Send(SFTP_DATAID_STC_RENAME, nLen, pData, status))
 		{
 			delete [] pData;
 			DoClose();
@@ -2194,10 +2398,44 @@
 			while (p=strstr(str, "\n"))
 			{
 				*p = 0;
-				ShowStatus(str, 3);
+				if (m_bUTF8) {
+					USES_CONVERSION;
+
+					// convert from UTF-8 to ANSI
+					int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, -1, NULL, 0);
+					if (len != 0)
+					{
+						LPWSTR p1 = new WCHAR[len + 1];
+						MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, -1 , (LPWSTR)p1, len*2);
+						CString tempstr = W2CT(p1);
+						delete [] p1;
+						ShowStatus(tempstr, 3);
+					}
+					else
+						ShowStatus(str, 3);
+				}
+				else
+					ShowStatus(str, 3);
 				str = p+1;
 			}
-			ShowStatus(str, 3);
+			if (m_bUTF8) {
+				USES_CONVERSION;
+
+				// convert from UTF-8 to ANSI
+				int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, -1, NULL, 0);
+				if (len != 0)
+				{
+					LPWSTR p1 = new WCHAR[len + 1];
+					MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, -1 , (LPWSTR)p1, len*2);
+					CString tempstr = W2CT(p1);
+					delete [] p1;
+					ShowStatus(tempstr, 3);
+				}
+				else
+					ShowStatus(str, 3);
+			}
+			else
+				ShowStatus(str, 3);
 		}
 		break;
 	case SFTP_DATAID_CTS_CRITICALERROR:
@@ -2242,7 +2480,24 @@
 			ResetOperation(FZ_REPLY_ERROR);
 		else
 		{
-			ShowStatus((char *)pData, 3);
+			if (m_bUTF8) {
+				USES_CONVERSION;
+
+				// convert from UTF-8 to ANSI
+				int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pData, -1, NULL, 0);
+				if (len != 0)
+				{
+					LPWSTR p1 = new WCHAR[len + 1];
+					MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pData, -1 , (LPWSTR)p1, len*2);
+					CString tempstr = W2CT(p1);
+					delete [] p1;
+					ShowStatus(tempstr, 3);
+				}
+				else
+					ShowStatus((char *)pData, 3);
+			}
+			else
+				ShowStatus((char *)pData, 3);
 			ProcessReply();
 		}
 		break;
@@ -2921,14 +3176,32 @@
 	USES_CONVERSION;
 	m_Operation.nOpMode=CSMODE_CHMOD;
 	CString str;
+	CString status;
+	int nLen;
+	char *pData;
 	str.Format( _T("%d %s%s"), nValue, path.GetPath(), filename);
-	int nLen = strlen(T2CA(str)) + 1;
-	char *pData=new char[nLen];
-	strcpy(pData, T2CA(str));
-	int pos(str.Find( _T(" ") ));
-	ASSERT(pos!=-1);
-	pData[pos]=0;
-	if (!m_pDataChannel->Send(SFTP_DATAID_STC_CHMOD, nLen, pData))
+	status = str;
+	if (m_bUTF8) {
+		LPCWSTR unicode = T2CW(str);
+		int len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, 0, 0, 0, 0);
+		char* utf8 = new char[len + 1];
+		WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf8, len + 1, 0, 0);
+		nLen=strlen(utf8)+1;
+		pData=new char[nLen];
+		strcpy(pData, utf8);
+		int pos(str.Find( _T(" ") ));
+		ASSERT(pos!=-1);
+		pData[pos]=0;
+	}
+	else {
+		nLen=strlen(T2CA(str))+1;
+		pData=new char[nLen];
+		strcpy(pData, T2CA(str));
+		int pos(str.Find( _T(" ") ));
+		ASSERT(pos!=-1);
+		pData[pos]=0;
+	}
+	if (!m_pDataChannel->Send(SFTP_DATAID_STC_CHMOD, nLen, pData, status))
 		DoClose();
 	delete [] pData;
 }
diff -Nur source/SftpControlSocket.h source.patch/SftpControlSocket.h
--- source/SftpControlSocket.h	Mon Mar 14 15:49:40 2005
+++ source.patch/SftpControlSocket.h	Tue Mar 15 11:37:15 2005
@@ -37,6 +37,7 @@
 class CSFtpControlSocket : public CControlSocket
 {
 public:
+	bool m_bUTF8;
 	BOOL m_bError;
 	void OnClientError(int nErrorCode);
 	int OnClientRequest(int nId, int &nDataLength, LPVOID pData);
