123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616 |
- #include "stdafx.h"
- #include "resource.h"
- #include "DataSocket.h"
- #include "ConnectSocket.h"
- #include "ConnectThread.h"
- #include <afxpriv.h>
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #define PACKET_SIZE 4096
- CDataSocket::CDataSocket(CConnectSocket *pSocket, int nTransferType)
- {
- m_nTransferType = nTransferType;
- m_pConnectSocket = pSocket;
- m_nStatus = XFERMODE_IDLE;
- m_strData = "";
- m_File.m_hFile = NULL;
- m_bConnected = FALSE;
- m_dwRestartOffset = 0;
- m_bInitialized = FALSE;
- }
- CDataSocket::~CDataSocket()
- {
- m_bConnected = FALSE;
- TRACE0("CDataSocket destroyed.\n");
- }
- #if 0
- BEGIN_MESSAGE_MAP(CDataSocket, CAsyncSocket)
-
-
- END_MESSAGE_MAP()
- #endif
- void CDataSocket::OnSend(int nErrorCode)
- {
- CAsyncSocket::OnSend(nErrorCode);
- switch(m_nStatus)
- {
- case XFERMODE_LIST:
- {
- while (m_nTotalBytesTransfered < m_nTotalBytesSend)
- {
- DWORD dwRead;
- int dwBytes;
- CString strData;
-
- dwRead = m_strData.GetLength();
-
- if (dwRead <= PACKET_SIZE)
- {
- strData = m_strData;
- }
- else
- {
- strData = m_strData.Left(PACKET_SIZE);
- dwRead = strData.GetLength();
- }
-
- if ((dwBytes = Send(strData, dwRead)) == SOCKET_ERROR)
- {
- if (GetLastError() == WSAEWOULDBLOCK)
- {
- Sleep(0);
- break;
- }
- else
- {
- TCHAR szError[256];
- wsprintf(szError, "Server Socket failed to send: %d", GetLastError());
-
- Close();
- m_nTotalBytesSend = 0;
- m_nTotalBytesTransfered = 0;
-
- m_nStatus = XFERMODE_IDLE;
- m_pConnectSocket->SendResponse("426 Connection closed; transfer aborted.");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
- }
- }
- else
- {
- m_nTotalBytesTransfered += dwBytes;
- m_strData = m_strData.Mid(dwBytes);
-
- ((CConnectThread *)AfxGetThread())->IncSentBytes(dwBytes);
- }
- }
- if (m_nTotalBytesTransfered == m_nTotalBytesSend)
- {
-
- Close();
- m_nTotalBytesSend = 0;
- m_nTotalBytesTransfered = 0;
-
- m_nStatus = XFERMODE_IDLE;
-
- m_pConnectSocket->SendResponse("226 Transfer complete");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
- }
- break;
- }
- case XFERMODE_SEND:
- {
- while (m_nTotalBytesTransfered < m_nTotalBytesSend)
- {
-
- byte data[PACKET_SIZE];
-
- m_File.Seek(m_nTotalBytesTransfered, CFile::begin);
- DWORD dwRead = m_File.Read(data, PACKET_SIZE);
-
- int dwBytes;
- if ((dwBytes = Send(data, dwRead)) == SOCKET_ERROR)
- {
- if (GetLastError() == WSAEWOULDBLOCK)
- {
- Sleep(0);
- break;
- }
- else
- {
- TCHAR szError[256];
- wsprintf(szError, "Server Socket failed to send: %d", GetLastError());
-
- m_File.Close();
- m_File.m_hFile = NULL;
-
- Close();
- m_nTotalBytesSend = 0;
- m_nTotalBytesTransfered = 0;
-
- m_nStatus = XFERMODE_IDLE;
- m_pConnectSocket->SendResponse("426 Connection closed; transfer aborted.");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
-
- ((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_DOWNLOADFAILED);
- }
- }
- else
- {
- m_nTotalBytesTransfered += dwBytes;
-
- ((CConnectThread *)AfxGetThread())->IncSentBytes(dwBytes);
- }
- }
- if (m_nTotalBytesTransfered == m_nTotalBytesSend)
- {
-
- m_File.Close();
- m_File.m_hFile = NULL;
-
- Close();
- m_nTotalBytesSend = 0;
- m_nTotalBytesTransfered = 0;
-
- m_nStatus = XFERMODE_IDLE;
-
- m_pConnectSocket->SendResponse("226 Transfer complete");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
-
- ((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_DOWNLOADSUCCEEDED);
- }
- break;
- }
- }
- }
- void CDataSocket::OnConnect(int nErrorCode)
- {
- if (nErrorCode)
- {
- m_nStatus = XFERMODE_ERROR;
- m_pConnectSocket->SendResponse("425 Can't open data connection.");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
- }
- else
- {
- switch (m_nTransferType)
- {
- case 0:
- m_nStatus = XFERMODE_LIST;
- m_bConnected = TRUE;
- OnSend(0);
- break;
- case 1:
- if (PrepareSendFile(m_strData))
- {
- m_nStatus = XFERMODE_SEND;
- m_bConnected = TRUE;
- }
- else
- {
- Close();
- }
- break;
- case 2:
- if (PrepareReceiveFile(m_strData))
- {
- m_nStatus = XFERMODE_RECEIVE;
- m_bConnected = TRUE;
- }
- else
- {
- Close();
- m_pConnectSocket->SendResponse("450 can't access file.");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
-
- ((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADFAILED);
- }
- break;
- }
- }
- CAsyncSocket::OnConnect(nErrorCode);
- }
- void CDataSocket::OnClose(int nErrorCode)
- {
- TRACE0("CDataSocket() OnClose()\n");
- if (m_pConnectSocket)
- {
-
- ShutDown(1);
- if (m_nStatus == XFERMODE_RECEIVE)
- {
- while(Receive() != 0)
- {
-
- }
- }
- else
- {
- m_pConnectSocket->SendResponse("426 Connection closed; transfer aborted.");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
-
- ((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADFAILED);
- }
- }
- m_nStatus = XFERMODE_IDLE;
- m_bConnected = FALSE;
- CAsyncSocket::OnClose(nErrorCode);
- }
- void CDataSocket::OnAccept(int nErrorCode)
- {
-
- CAsyncSocket tmpSocket;
- Accept(tmpSocket);
-
- SOCKET socket = tmpSocket.Detach();
- Close();
- Attach(socket);
- m_bConnected = TRUE;
- if (!m_bInitialized)
- SetTransferType(m_nTransferType);
-
- CAsyncSocket::OnAccept(nErrorCode);
- }
- int CDataSocket::GetStatus()
- {
- return m_nStatus;
- }
- BOOL CDataSocket::PrepareSendFile(LPCTSTR lpszFilename)
- {
-
- if (m_File.m_hFile != NULL)
- {
- m_File.Close();
- }
-
- if (!m_File.Open(lpszFilename, CFile::modeRead | CFile::typeBinary))
- {
- return FALSE;
- }
- m_nTotalBytesSend = m_File.GetLength();
- if (m_dwRestartOffset < m_nTotalBytesSend)
- m_nTotalBytesTransfered = m_dwRestartOffset;
- else
- m_nTotalBytesTransfered = 0;
- return TRUE;
- }
- BOOL CDataSocket::PrepareReceiveFile(LPCTSTR lpszFilename)
- {
-
- if (m_File.m_hFile != NULL)
- {
- m_File.Close();
- }
-
- if (!m_File.Open(lpszFilename, CFile::modeWrite | CFile::modeCreate | CFile::modeNoTruncate | CFile::shareDenyWrite))
- {
- return FALSE;
- }
- m_nTotalBytesReceive = 0;
- m_nTotalBytesTransfered = 0;
- if (m_dwRestartOffset)
- {
- m_File.SetLength(m_dwRestartOffset);
- m_File.SeekToEnd();
- }
- return TRUE;
- }
- void CDataSocket::OnReceive(int nErrorCode)
- {
- CAsyncSocket::OnReceive(nErrorCode);
-
- Receive();
- }
- int CDataSocket::Receive()
- {
- int nRead = 0;
-
- if (m_nStatus == XFERMODE_RECEIVE)
- {
- if (m_File.m_hFile == NULL)
- return 0;
- byte data[PACKET_SIZE];
- nRead = CAsyncSocket::Receive(data, PACKET_SIZE);
- switch(nRead)
- {
- case 0:
- {
- m_File.Close();
- m_File.m_hFile = NULL;
- Close();
-
- m_pConnectSocket->SendResponse("226 Transfer complete");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
-
- ((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADSUCCEEDED);
- break;
- }
- case SOCKET_ERROR:
- {
- if (GetLastError() != WSAEWOULDBLOCK)
- {
- m_File.Close();
- m_File.m_hFile = NULL;
- Close();
- m_pConnectSocket->SendResponse("426 Connection closed; transfer aborted.");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
-
- ((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADFAILED);
- }
- break;
- }
- default:
- {
- ((CConnectThread *)AfxGetThread())->IncReceivedBytes(nRead);
- TRY
- {
- m_File.Write(data, nRead);
- }
- CATCH_ALL(e)
- {
- m_File.Close();
- m_File.m_hFile = NULL;
- Close();
- m_pConnectSocket->SendResponse("450 Can't access file.");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
-
- ((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADFAILED);
- return 0;
- }
- END_CATCH_ALL;
- break;
- }
- }
- }
- return nRead;
- }
- void CDataSocket::SetData(LPCTSTR lpszData)
- {
- m_strData = lpszData;
- m_nTotalBytesSend = m_strData.GetLength();
- m_nTotalBytesTransfered = 0;
- }
- void CDataSocket::SetTransferType(int nType, BOOL bWaitForAccept)
- {
- m_nTransferType = nType;
- if (bWaitForAccept && !m_bConnected)
- {
- m_bInitialized = FALSE;
- return;
- }
- if (m_bConnected && m_nTransferType != -1)
- m_pConnectSocket->SendResponse("150 Connection accepted");
- m_bInitialized = TRUE;
- switch(m_nTransferType)
- {
- case 0:
- m_nStatus = XFERMODE_LIST;
- OnSend(0);
- break;
- case 1:
- if (PrepareSendFile(m_strData))
- {
- m_nStatus = XFERMODE_SEND;
- m_bConnected = TRUE;
- OnSend(0);
- }
- else
- {
- Close();
- }
- break;
- case 2:
- if (PrepareReceiveFile(m_strData))
- {
- m_nStatus = XFERMODE_RECEIVE;
- m_bConnected = TRUE;
- OnSend(0);
- }
- else
- {
- Close();
- m_pConnectSocket->SendResponse("450 Can't access file.");
-
- AfxGetThread()->PostThreadMessage(WM_THREADMSG, 0, 0);
-
- ((CConnectThread *)AfxGetThread())->UpdateStatistic(FTPSTAT_UPLOADFAILED);
- }
- break;
- default:
- m_bInitialized = FALSE;
- break;
- }
- }
- void CDataSocket::SetRestartOffset(DWORD dwOffset)
- {
- m_dwRestartOffset = dwOffset;
- }
|