diff -Nur source.orig\FtpControlSocket.cpp source\FtpControlSocket.cpp
--- source.orig\FtpControlSocket.cpp	Sat Jan 15 19:46:52 2005
+++ source\FtpControlSocket.cpp	Mon Feb 28 23:38:41 2005
@@ -146,6 +146,9 @@
 	m_useZlib = false;
 	m_zlibSupported = false;
 	m_zlibLevel = 8;
+
+	m_bUTF8 = false;
+	m_RecvBufferA = "";
 }
 
 CFtpControlSocket::~CFtpControlSocket()
@@ -552,8 +555,10 @@
 	{ // authentication succeeded, we're now get the response to the CWD command
 		if (GetReplyCode() == 2) // we're logged on
 		{
-			if (Send("FEAT"))
+			if (Send("FEAT")) {
+				m_bUTF8 = false;
 				m_Operation.nOpState = CONNECT_FEAT;
+			}
 			return;
 		}
 		else
@@ -581,8 +586,10 @@
 			DoClose();
 			return;
 		case LO: //LO means we are logged on
-			if (Send("FEAT"))
+			if (Send("FEAT")) {
+				m_bUTF8 = false;
 				m_Operation.nOpState = CONNECT_FEAT;
+			}
 			return;
 		}
 	}
@@ -659,6 +666,7 @@
 			temp="PASS "+m_CurrentServer.pass+"@"+CCrypt::decrypt(COptions::GetOption(OPTION_FWPASS));
 			break;
 	}
+	m_bUTF8 = false;
 	// send command, get response
 	if(!Send(temp))
 		return;
@@ -694,8 +702,32 @@
 		{
 			if ((buffer[i]=='\r')||(buffer[i]=='\n')||(buffer[i]==0))
 			{
-				if (!m_RecvBuffer.empty() && m_RecvBuffer.back()!=_T("") )
+				if (!m_RecvBuffer.empty() && m_RecvBufferA!="" )
 				{
+					if (m_bUTF8) {
+#if defined(_UNICODE)
+						// convert from UTF-8 to Unicode
+						int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_RecvBufferA, -1, NULL, 0);
+						wchar_t *p2 = new wchar_t[len * 2 + 1];
+						MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_RecvBufferA, -1, (LPWSTR)p2, len*2);
+						m_RecvBuffer.back() = p2;
+						delete [] p2;
+#else
+						// convert from UTF-8 to ANSI
+						int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_RecvBufferA, -1, NULL, 0);
+						char *p1 = new char[len * 2 + 1];
+						char *p2 = new char[len * 2 + 1];
+						MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)m_RecvBufferA, -1 , (LPWSTR)p1, len*2);
+						WideCharToMultiByte(CP_ACP, 0,(LPCWSTR)p1, -1, p2, len*2, NULL, NULL);
+						m_RecvBuffer.back() = p2;
+						delete [] p1;
+						delete [] p2;
+#endif
+					}
+					else {
+						USES_CONVERSION;
+						m_RecvBuffer.back() = A2CT(m_RecvBufferA);
+					}
 					ShowStatus(m_RecvBuffer.back(), 3);
 					//Check for multi-line responses
 					if (m_RecvBuffer.back().GetLength()>3)
@@ -726,16 +758,19 @@
 					else
 						m_RecvBuffer.pop_back();
 					m_RecvBuffer.push_back(_T(""));
+					m_RecvBufferA = "";
 				}
 			}
 			else
 			{
 				//The command may only be 2000 chars long. This ensures that a malicious user can't
 				//send extremely large commands to fill the memory of the server
-				if (m_RecvBuffer.empty())
+				if (m_RecvBuffer.empty()) {
 					m_RecvBuffer.push_back(_T(""));
-				if (m_RecvBuffer.back().GetLength()<2000)
-					m_RecvBuffer.back()+=buffer[i];
+					m_RecvBufferA = "";
+				}
+				if (m_RecvBufferA.GetLength()<2000)
+					m_RecvBufferA+=buffer[i];
 			}
 		}
 		if (numread<BUFFERSIZE)
@@ -832,8 +867,31 @@
 	
 	ShowStatus(str,2);
 	str+="\r\n";
-	LPCSTR lpszAsciiSend=T2CA(str);
-	int res = CAsyncSocketEx::Send(lpszAsciiSend,strlen(lpszAsciiSend));
+	int res;
+	if (m_bUTF8) {
+#if defined(_UNICODE)
+		// Convert Unicode to UTF-8
+		int len = str.GetLength() * 6;
+		char *p1 = new char[len + 1];
+		WideCharToMultiByte(CP_UTF8, 0, str, -1, p1, len, NULL, NULL);
+		res = CAsyncSocketEx::Send(p1, strlen(p1));
+		delete [] p1;
+#else
+		// Convert ANSI to UTF-8
+		int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+		char *p1 = new char[len * 2 + 1];
+		char *p2 = new char[len * 2 + 1];
+		MultiByteToWideChar(CP_ACP, 0, str, -1 , (LPWSTR)p1, len*2);
+		WideCharToMultiByte(CP_UTF8, 0,(LPCWSTR)p1, -1, p2, len*2, NULL, NULL);
+		res = CAsyncSocketEx::Send(p2, strlen(p2));
+		delete [] p1;
+		delete [] p2;
+#endif
+	}
+	else {
+		LPCSTR lpszAsciiSend=T2CA(str);
+		res = CAsyncSocketEx::Send(lpszAsciiSend,strlen(lpszAsciiSend));
+	}
 	if (!res)
 	{
 		if (GetLastError()!=WSAEWOULDBLOCK)
@@ -871,13 +929,16 @@
 		nError |= FZ_REPLY_ERROR;
 	ResetOperation(FZ_REPLY_ERROR|FZ_REPLY_DISCONNECTED|nError);
 	m_RecvBuffer.clear();
-	m_MultiLine = "";
+	m_MultiLine = _T("");
+	m_RecvBufferA = "";
 	m_bDidRejectCertificate = FALSE;
 
 	m_useZlib = false;
 	m_zlibSupported = false;
 	m_zlibLevel = 0;
 
+	m_bUTF8 = false;
+
 	CControlSocket::Close();
 }
 
@@ -4875,6 +4936,8 @@
 		line.MakeUpper();
 		if (line == _T(" MODE Z") || line.Left(8) == _T(" MODE Z "))
 			m_zlibSupported = true;
+		if (line == _T(" UTF8") || line.Left(8) == _T(" UTF8 "))
+			m_bUTF8 = true;
 	}
 }
 
diff -Nur source.orig\FtpControlSocket.h source\FtpControlSocket.h
--- source.orig\FtpControlSocket.h	Mon Jun 07 22:59:10 2004
+++ source\FtpControlSocket.h	Mon Feb 28 23:25:03 2005
@@ -120,6 +120,7 @@
 	CTime m_LastSendTime;
 	
 	CString m_ServerName;
+	CStringA m_RecvBufferA;
 	std::list<CString> m_RecvBuffer;
 	CTime m_LastRecvTime;
 	class CListData;
@@ -129,6 +130,8 @@
 	bool m_useZlib;
 	bool m_zlibSupported;
 	int m_zlibLevel;
+
+	bool m_bUTF8;
 
 private:
 	BOOL m_bCheckForTimeout;
diff -Nur source.orig\FtpListResult.cpp source\FtpListResult.cpp
--- source.orig\FtpListResult.cpp	Sun Feb 27 00:35:57 2005
+++ source\FtpListResult.cpp	Mon Feb 28 23:47:52 2005
@@ -142,11 +142,12 @@
 
 #endif
 
-CFtpListResult::CFtpListResult(t_server server)
+CFtpListResult::CFtpListResult(t_server server, bool bUTF8)
 {
 	listhead=curpos=0;
 	
 	m_server = server;
+	m_bUTF8 = bUTF8;
 
 	pos=0;
 
@@ -2129,12 +2130,71 @@
 
 void CFtpListResult::copyStr(CString &target, int pos, const char *source, int len) const
 {
-	int i;
-	LPTSTR pBuffer = target.GetBuffer(pos + len);
-	ASSERT(pBuffer);
-	for (i = 0; i < len; i++)
-		pBuffer[pos + i] = source[i];
-	target.ReleaseBuffer(pos + len);
+#if defined(_UNICODE)
+	if (m_bUTF8) {
+		char *p = new char[len+1];
+		memcpy(p, source, len);
+		p[len] = '\0';
+		// convert from UTF-8 to Unicode
+		int len = MultiByteToWideChar(CP_UTF8, 0, p, -1, NULL, 0);
+		wchar_t *p2 = new wchar_t[len * 2 + 1];
+		MultiByteToWideChar(CP_UTF8, 0, p, -1 , (LPWSTR)p2, len*2);
+		int i;
+		int ulen = wcslen(p2);
+		LPTSTR pBuffer = target.GetBuffer(pos + ulen);
+		ASSERT(pBuffer);
+		for (i = 0; i < ulen; i++)
+			pBuffer[pos + i] = p2[i];
+		target.ReleaseBuffer(pos + ulen);
+		delete [] p;
+		delete [] p2;
+	}
+	else {
+		USES_CONVERSION;
+		char *p = new char[len+1];
+		memcpy(p, source, len);
+		p[len] = '\0';
+		CString tempstr = A2CT(p);
+		int i;
+		int ulen = tempstr.GetLength();
+		LPTSTR pBuffer = target.GetBuffer(pos + ulen);
+		ASSERT(pBuffer);
+		for (i = 0; i < ulen; i++)
+			pBuffer[pos + i] = tempstr[i];
+		target.ReleaseBuffer(pos + ulen);
+		delete [] p;
+	}
+#else
+	if (m_bUTF8) {
+		char *p = new char[len+1];
+		memcpy(p, source, len);
+		p[len] = '\0';
+		// convert from UTF-8 to ANSI
+		int len = MultiByteToWideChar(CP_UTF8, 0, p, -1, NULL, 0);
+		char *p1 = new char[len * 2 + 1];
+		char *p2 = new char[len * 2 + 1];
+		MultiByteToWideChar(CP_UTF8, 0, p, -1 , (LPWSTR)p1, len*2);
+		WideCharToMultiByte(CP_ACP, 0,(LPCWSTR)p1, -1, p2, len*2, NULL, NULL);
+		int i;
+		int ulen = strlen(p2);
+		LPTSTR pBuffer = target.GetBuffer(pos + ulen);
+		ASSERT(pBuffer);
+		for (i = 0; i < ulen; i++)
+			pBuffer[pos + i] = p2[i];
+		target.ReleaseBuffer(pos + ulen);
+		delete [] p;
+		delete [] p1;
+		delete [] p2;
+	}
+	else {
+		int i;
+		LPTSTR pBuffer = target.GetBuffer(pos + len);
+		ASSERT(pBuffer);
+		for (i = 0; i < len; i++)
+			pBuffer[pos + i] = source[i];
+		target.ReleaseBuffer(pos + len);
+	}
+#endif
 }
 
 BOOL CFtpListResult::parseAsIBM(const char *line, const int linelen, t_directory::t_direntry &direntry)
diff -Nur source.orig\FtpListResult.h source\FtpListResult.h
--- source.orig\FtpListResult.h	Fri Jan 14 14:50:46 2005
+++ source\FtpListResult.h	Sun Feb 27 00:16:17 2005
@@ -55,9 +55,10 @@
 {
 public:
 	t_server m_server;
+	bool m_bUTF8;
 	void SendToMessageLog(HWND hWnd, UINT nMsg);
 	void AddData(char *data,int size);
-	CFtpListResult(t_server server);
+	CFtpListResult(t_server server, bool bUTF8 = false);
 	~CFtpListResult();
 	t_directory::t_direntry *getList(int &num, CTime EntryTime);
 
diff -Nur source.orig\StatusCtrl.cpp source\StatusCtrl.cpp
--- source.orig\StatusCtrl.cpp	Wed Oct 27 16:18:18 2004
+++ source\StatusCtrl.cpp	Sun Feb 27 20:54:51 2005
@@ -135,7 +135,7 @@
 
 	rtfstr += "} ";
 
-	char *buffer = new char[rtfstr.GetLength() + 5];
+	char *buffer = new char[rtfstr.GetLength()*2 + 5];
 	strcpy(buffer + 4, T2CA(rtfstr));
 	*(int *)buffer = 0;
 
@@ -279,7 +279,7 @@
 	CString rtfstr = m_RTFHeader;
 	rtfstr += "} ";
 
-	char *buffer = new char[rtfstr.GetLength() + 5];
+	char *buffer = new char[rtfstr.GetLength()*2 + 5];
 	strcpy(buffer + 4, T2CA(rtfstr));
 	*(int *)buffer = 0;
 
@@ -324,7 +324,7 @@
 		__time64_t t = _time64(0);
 		if (!strftime(buf, 100, "[%H:%M:%S] ", _localtime64(&t)))
 			buf[0] = 0;
-		CString stime = A2CT(buf);
+		stime = A2CT(buf);
 	}
 
 	CString str;
@@ -371,7 +371,7 @@
 	
 	rtfstr += "} ";
 
-	char *buffer = new char[rtfstr.GetLength() + 5]; //Make it large enough to hold unicode data
+	char *buffer = new char[rtfstr.GetLength()*2 + 5]; //Make it large enough to hold unicode data
 	strcpy(buffer + 4, T2CA(rtfstr));
 	*(int *)buffer = 0;
 
diff -Nur source.orig\TransferSocket.cpp source\TransferSocket.cpp
--- source.orig\TransferSocket.cpp	Sun Feb 20 12:30:52 2005
+++ source\TransferSocket.cpp	Sun Feb 27 00:14:15 2005
@@ -79,7 +79,7 @@
 	m_pSslLayer = NULL;
 	m_pGssLayer = NULL;
 
-	m_pListResult = new CFtpListResult(pOwner->m_CurrentServer);
+	m_pListResult = new CFtpListResult(pOwner->m_CurrentServer, pOwner->m_bUTF8);
 	m_LastUpdateTime.QuadPart = 0;
 
 	memset(&m_zlibStream, 0, sizeof(m_zlibStream));
