home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 217 / DPCS0306DVD.ISO / Toolkit / Internet / FileZilla / Server / FileZilla_Server-0.9.11.exe / source / TransferSocket.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-08-30  |  32.7 KB  |  1,289 lines

  1. // FileZilla Server - a Windows ftp server
  2.  
  3. // Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>
  4.  
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9.  
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14.  
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. // TransferSocket.cpp: Implementierungsdatei
  20. //
  21.  
  22. #include "stdafx.h"
  23. #include "TransferSocket.h"
  24. #include "ControlSocket.h"
  25. #include "options.h"
  26. #include "ServerThread.h"
  27. #include "AsyncGssSocketLayer.h"
  28. #include "AsyncSslSocketLayer.h"
  29. #include "Permissions.h"
  30.  
  31. #ifdef _DEBUG
  32. #undef THIS_FILE
  33. static char THIS_FILE[] = __FILE__;
  34. #endif
  35.  
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CTransferSocket
  38. CTransferSocket::CTransferSocket(CControlSocket *pOwner)
  39. {
  40.     ASSERT(pOwner);
  41.     m_pOwner = pOwner;
  42.     m_status = 0;
  43.     m_nMode = TRANSFERMODE_NOTSET;
  44.  
  45.     m_nBufferPos = NULL;
  46.     m_pBuffer = NULL;
  47.     m_pDirListing = NULL;
  48.     bAccepted = FALSE;
  49.  
  50.     m_bSentClose = FALSE;
  51.  
  52.     m_bReady = FALSE;
  53.     m_bStarted = FALSE;
  54.     GetSystemTime(&m_LastActiveTime);
  55.     m_wasActiveSinceCheck = false;
  56.     m_nRest = 0;
  57.  
  58.     m_pGssLayer = 0;
  59.     m_pSslLayer = 0;
  60.  
  61.     m_hFile = INVALID_HANDLE_VALUE;
  62.  
  63.     m_nBufSize = (int)m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_BUFFERSIZE);
  64.  
  65.     m_useZlib = false;
  66.     memset(&m_zlibStream, 0, sizeof(m_zlibStream));
  67.  
  68.     m_zlibBytesIn = 0;
  69.     m_zlibBytesOut = 0;
  70.  
  71.     m_pBuffer2 = 0;
  72.     
  73.     m_currentFileOffset = 0;
  74. }
  75.  
  76. void CTransferSocket::Init(t_dirlisting *pDir, int nMode)
  77. {
  78.     ASSERT(nMode==TRANSFERMODE_LIST || nMode==TRANSFERMODE_NLST);
  79.     ASSERT(pDir);
  80.     m_bReady = TRUE;
  81.     m_status = 0;
  82.     if (m_pBuffer)
  83.         delete [] m_pBuffer;
  84.     m_pBuffer = 0;
  85.     if (m_pBuffer2)
  86.         delete [] m_pBuffer2;
  87.     m_pBuffer2 = 0;
  88.     
  89.     m_pDirListing = pDir;
  90.  
  91.     m_nMode = nMode;
  92.  
  93.     if (m_hFile != INVALID_HANDLE_VALUE)
  94.         CloseHandle(m_hFile);
  95.     m_nBufferPos = 0;
  96. }
  97.  
  98. void CTransferSocket::Init(CStdString filename, int nMode, _int64 rest)
  99. {
  100.     ASSERT(nMode == TRANSFERMODE_SEND || nMode == TRANSFERMODE_RECEIVE);
  101.     m_bReady = TRUE;
  102.     m_Filename = filename;
  103.     m_nRest = rest;
  104.     m_nMode = nMode;
  105.  
  106.     if (m_pBuffer)
  107.         delete [] m_pBuffer;
  108.     m_pBuffer = 0;
  109.     if (m_pBuffer2)
  110.         delete [] m_pBuffer2;
  111.     m_pBuffer2 = 0;
  112. }
  113.  
  114. CTransferSocket::~CTransferSocket()
  115. {
  116.     delete [] m_pBuffer;
  117.     delete [] m_pBuffer2;
  118.     if (m_hFile != INVALID_HANDLE_VALUE)
  119.     {
  120.         CloseHandle(m_hFile);
  121.         m_hFile = INVALID_HANDLE_VALUE;
  122.     }
  123.  
  124.     RemoveAllLayers();
  125.     delete m_pGssLayer;
  126.     delete m_pSslLayer;
  127.  
  128.     while (m_pDirListing)
  129.     {
  130.         t_dirlisting *pPrev = m_pDirListing;
  131.         m_pDirListing = m_pDirListing->pNext;
  132.         delete pPrev;
  133.     }
  134.  
  135.     if (m_useZlib)
  136.     {
  137.         if (m_nMode == TRANSFERMODE_RECEIVE)
  138.             inflateEnd(&m_zlibStream);
  139.         else
  140.             deflateEnd(&m_zlibStream);
  141.     }
  142. }
  143.  
  144.  
  145. //Die folgenden Zeilen nicht bearbeiten. Sie werden vom Klassen-Assistenten ben÷tigt.
  146. #if 0
  147. BEGIN_MESSAGE_MAP(CTransferSocket, CAsyncSocketEx)
  148.     //{{AFX_MSG_MAP(CTransferSocket)
  149.     //}}AFX_MSG_MAP
  150. END_MESSAGE_MAP()
  151. #endif    // 0
  152.  
  153. /////////////////////////////////////////////////////////////////////////////
  154. // Member-Funktion CTransferSocket
  155.  
  156. void CTransferSocket::OnSend(int nErrorCode)
  157. {
  158.     CAsyncSocketEx::OnSend(nErrorCode);
  159.     if (nErrorCode)
  160.     {
  161.         if (m_hFile != INVALID_HANDLE_VALUE)
  162.             CloseHandle(m_hFile);
  163.         m_hFile = INVALID_HANDLE_VALUE;
  164.         m_status=1;
  165.         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  166.         Close();
  167.         return;
  168.     }
  169.  
  170.     if (m_nMode == TRANSFERMODE_LIST || m_nMode == TRANSFERMODE_NLST)
  171.     { //Send directory listing
  172.         if (!m_bStarted)
  173.             if (!InitTransfer(TRUE))
  174.                 return;
  175.  
  176.         if (m_useZlib)
  177.         {
  178.             if (!m_pBuffer)
  179.             {
  180.                 m_pBuffer = new char[m_nBufSize];
  181.                 m_nBufferPos = 0;
  182.  
  183.                 m_zlibStream.next_in = (Bytef *)m_pBuffer; // Make sure next_in is not 0 in all cases
  184.  
  185.                 m_zlibStream.next_out = (Bytef *)m_pBuffer;
  186.                 m_zlibStream.avail_out = m_nBufSize;
  187.             }
  188.  
  189.             while (true)
  190.             {
  191.                 int numsend;
  192.                 if (!m_zlibStream.avail_in)
  193.                 {
  194.                     if (m_pDirListing)
  195.                     {
  196.                         m_zlibStream.next_in = (Bytef *)m_pDirListing->buffer;
  197.                         m_zlibStream.avail_in = m_pDirListing->len;
  198.                     }
  199.                 }
  200.                 if (!m_zlibStream.avail_out)
  201.                 {
  202.                     if (m_nBufferPos >= m_nBufSize)
  203.                     {
  204.                         m_nBufferPos = 0;
  205.                         m_zlibStream.next_out = (Bytef *)m_pBuffer;
  206.                         m_zlibStream.avail_out = m_nBufSize;
  207.                     }
  208.                 }
  209.  
  210.                 int res = Z_OK;
  211.                 if (m_zlibStream.avail_out)
  212.                 {
  213.                     m_zlibStream.total_in = 0;
  214.                     m_zlibStream.total_out = 0;
  215.                     res = deflate(&m_zlibStream, (m_pDirListing && m_pDirListing->pNext) ? 0 : Z_FINISH);
  216.                     m_currentFileOffset += m_zlibStream.total_in;
  217.                     m_zlibBytesIn += m_zlibStream.total_in;
  218.                     m_zlibBytesOut += m_zlibStream.total_out;
  219.                     if (res == Z_STREAM_END)
  220.                     {
  221.                         if (m_pDirListing && m_pDirListing->pNext)
  222.                         {
  223.                             Close();
  224.                             m_status = 6;
  225.                             m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  226.                             return;
  227.                         }
  228.                         if (!(m_nBufSize - m_nBufferPos - m_zlibStream.avail_out))
  229.                             break;
  230.                     }
  231.                     else if (res != Z_OK)
  232.                     {
  233.                         Close();
  234.                         m_status = 6;
  235.                         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  236.                         return;
  237.                     }
  238.                     if (!m_zlibStream.avail_in && m_pDirListing)
  239.                     {
  240.                         t_dirlisting *pPrev = m_pDirListing;
  241.                         m_pDirListing = m_pDirListing->pNext;
  242.                         delete pPrev;
  243.                     }
  244.                 }
  245.                 
  246.                 numsend = m_nBufSize;
  247.                 unsigned int len = m_nBufSize - m_nBufferPos - m_zlibStream.avail_out;
  248.                 if (!len)
  249.                     continue;
  250.  
  251.                 if (len < m_nBufSize)
  252.                     numsend = len;
  253.                 
  254.                 int nLimit = m_pOwner->GetSpeedLimit(download);
  255.                 if (nLimit != -1 && GetState() != aborted && numsend > nLimit)
  256.                     numsend = nLimit;
  257.  
  258.                 if (!numsend)
  259.                     return;
  260.  
  261.                 int numsent = Send(m_pBuffer + m_nBufferPos, numsend);
  262.                 if (numsent == SOCKET_ERROR)
  263.                 {
  264.                     if (GetLastError() != WSAEWOULDBLOCK)
  265.                     {
  266.                         Close();
  267.                         m_status = 1;
  268.                         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  269.                     }
  270.                     return;
  271.                 }
  272.  
  273.                 if (nLimit != -1 && GetState() != aborted)
  274.                     m_pOwner->m_SlQuotas[download].nTransferred += numsent;
  275.  
  276.                 ((CServerThread *)m_pOwner->m_pOwner)->IncSendCount(numsent);
  277.                 m_wasActiveSinceCheck = true;
  278.                 m_nBufferPos += numsent;
  279.  
  280.                 if (!m_zlibStream.avail_in && !m_pDirListing && m_zlibStream.avail_out &&
  281.                     m_zlibStream.avail_out + m_nBufferPos == m_nBufSize && res == Z_STREAM_END)
  282.                 {
  283.                     break;
  284.                 }
  285.  
  286.                 //Check if there are other commands in the command queue.
  287.                 MSG msg;
  288.                 if (PeekMessage(&msg,0, 0, 0, PM_NOREMOVE))
  289.                 {
  290.                     TriggerEvent(FD_WRITE);
  291.                     return;
  292.                 }
  293.             }
  294.         }
  295.         else
  296.         {
  297.             while (m_pDirListing && m_pDirListing->len)
  298.             {
  299.                 int numsend = m_nBufSize;
  300.                 if ((m_pDirListing->len - m_nBufferPos) < m_nBufSize)
  301.                     numsend = m_pDirListing->len - m_nBufferPos;
  302.  
  303.                 int nLimit = m_pOwner->GetSpeedLimit(download);
  304.                 if (nLimit != -1 && GetState() != aborted && numsend > nLimit)
  305.                     numsend = nLimit;
  306.  
  307.                 if (!numsend)
  308.                     return;
  309.  
  310.                 int numsent = Send(m_pDirListing->buffer + m_nBufferPos, numsend);
  311.                 if (numsent == SOCKET_ERROR)
  312.                 {
  313.                     int error = GetLastError();
  314.                     if (error != WSAEWOULDBLOCK)
  315.                     {
  316.                         Close();
  317.                         m_status = 1;
  318.                         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  319.                     }
  320.                     return;
  321.                 }
  322.  
  323.                 if (nLimit != -1 && GetState() != aborted)
  324.                     m_pOwner->m_SlQuotas[download].nTransferred += numsent;
  325.  
  326.                 ((CServerThread *)m_pOwner->m_pOwner)->IncSendCount(numsent);
  327.                 m_wasActiveSinceCheck = true;
  328.                 if (numsent < numsend)
  329.                     m_nBufferPos += numsent;
  330.                 else
  331.                     m_nBufferPos += numsend;
  332.                 
  333.                 m_currentFileOffset += numsent;
  334.  
  335.                 ASSERT(m_nBufferPos <= m_pDirListing->len);
  336.                 if (m_nBufferPos == m_pDirListing->len)
  337.                 {
  338.                     t_dirlisting *pPrev = m_pDirListing;
  339.                     m_pDirListing = m_pDirListing->pNext;
  340.                     delete pPrev;
  341.                     m_nBufferPos = 0;
  342.     
  343.                     if (!m_pDirListing)
  344.                         break;
  345.                 }
  346.  
  347.                 //Check if there are other commands in the command queue.
  348.                 MSG msg;
  349.                 if (PeekMessage(&msg,0, 0, 0, PM_NOREMOVE))
  350.                 {
  351.                     TriggerEvent(FD_WRITE);
  352.                     return;
  353.                 }
  354.             }
  355.         }
  356.  
  357.         if (m_pGssLayer || m_pSslLayer)
  358.             if (!ShutDown() && GetLastError() == WSAEWOULDBLOCK)
  359.                 return;
  360.         Close();
  361.         m_status = 0;
  362.         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  363.     }
  364.     else if (m_nMode == TRANSFERMODE_SEND)
  365.     { //Send file
  366.         if (!m_bStarted)
  367.             if (!InitTransfer(TRUE))
  368.                 return;
  369.         if (m_useZlib)
  370.         {
  371.             if (!m_pBuffer2)
  372.             {
  373.                 m_pBuffer2 = new char[m_nBufSize];
  374.  
  375.                 m_zlibStream.next_in = (Bytef *)m_pBuffer2;
  376.             }
  377.  
  378.             while (true)
  379.             {
  380.                 int numsend;
  381.                 if (!m_zlibStream.avail_in)
  382.                 {
  383.                     if (m_hFile != INVALID_HANDLE_VALUE)
  384.                     {
  385.                         DWORD numread;
  386.                         if (!ReadFile(m_hFile, m_pBuffer2, m_nBufSize, &numread, 0))
  387.                         {
  388.                             CloseHandle(m_hFile);
  389.                             m_hFile = INVALID_HANDLE_VALUE;
  390.                             Close();
  391.                             m_status = 3; //TODO: Better reason
  392.                             m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  393.                             return;
  394.                         }
  395.                         m_currentFileOffset += numread;
  396.  
  397.                         m_zlibStream.next_in = (Bytef *)m_pBuffer2;
  398.                         m_zlibStream.avail_in = numread;
  399.  
  400.                         if (numread < m_nBufSize)
  401.                         {
  402.                             CloseHandle(m_hFile);
  403.                             m_hFile = INVALID_HANDLE_VALUE;
  404.                         }
  405.                     }
  406.                 }
  407.                 if (!m_zlibStream.avail_out)
  408.                 {
  409.                     if (m_nBufferPos >= m_nBufSize)
  410.                     {
  411.                         m_nBufferPos = 0;
  412.                         m_zlibStream.next_out = (Bytef *)m_pBuffer;
  413.                         m_zlibStream.avail_out = m_nBufSize;
  414.                     }
  415.                 }
  416.  
  417.                 int res = Z_OK;
  418.                 if (m_zlibStream.avail_out)
  419.                 {
  420.                     m_zlibStream.total_in = 0;
  421.                     m_zlibStream.total_out = 0;
  422.                     res = deflate(&m_zlibStream, (m_hFile != INVALID_HANDLE_VALUE) ? 0 : Z_FINISH);
  423.                     m_zlibBytesIn += m_zlibStream.total_in;
  424.                     m_zlibBytesOut += m_zlibStream.total_out;
  425.                     if (res == Z_STREAM_END)
  426.                     {
  427.                         if (m_hFile != INVALID_HANDLE_VALUE)
  428.                         {
  429.                             Close();
  430.                             m_status = 6;
  431.                             m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  432.                             return;
  433.                         }
  434.                         if (!(m_nBufSize - m_nBufferPos - m_zlibStream.avail_out))
  435.                             break;
  436.                     }
  437.                     else if (res != Z_OK)
  438.                     {
  439.                         Close();
  440.                         m_status = 6;
  441.                         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  442.                         return;
  443.                     }
  444.                 }
  445.                     
  446.                 numsend = m_nBufSize;
  447.                 unsigned int len = m_nBufSize - m_nBufferPos - m_zlibStream.avail_out;
  448.                 if (!len)
  449.                     continue;
  450.  
  451.                 if (len < m_nBufSize)
  452.                     numsend = len;
  453.                 
  454.                 int nLimit = m_pOwner->GetSpeedLimit(download);
  455.                 if (nLimit != -1 && GetState() != aborted && numsend > nLimit)
  456.                     numsend = nLimit;
  457.  
  458.                 if (!numsend)
  459.                     return;
  460.  
  461.                 int numsent = Send(m_pBuffer + m_nBufferPos, numsend);
  462.                 if (numsent == SOCKET_ERROR)
  463.                 {
  464.                     if (GetLastError() != WSAEWOULDBLOCK)
  465.                     {
  466.                         Close();
  467.                         m_status = 1;
  468.                         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  469.                     }
  470.                     return;
  471.                 }
  472.  
  473.                 if (nLimit != -1 && GetState() != aborted)
  474.                     m_pOwner->m_SlQuotas[download].nTransferred += numsent;
  475.  
  476.                 ((CServerThread *)m_pOwner->m_pOwner)->IncSendCount(numsent);
  477.                 m_wasActiveSinceCheck = true;
  478.                 m_nBufferPos += numsent;
  479.  
  480.                 if (!m_zlibStream.avail_in && m_hFile == INVALID_HANDLE_VALUE && m_zlibStream.avail_out &&
  481.                     m_zlibStream.avail_out + m_nBufferPos == m_nBufSize && res == Z_STREAM_END)
  482.                 {
  483.                     break;
  484.                 }
  485.  
  486.                 //Check if there are other commands in the command queue.
  487.                 MSG msg;
  488.                 if (PeekMessage(&msg,0, 0, 0, PM_NOREMOVE))
  489.                 {
  490.                     TriggerEvent(FD_WRITE);
  491.                     return;
  492.                 }
  493.             }
  494.         }
  495.         else
  496.         {
  497.             while (m_hFile != INVALID_HANDLE_VALUE || m_nBufferPos)
  498.             {
  499.                 DWORD numread;
  500.                 if (m_nBufSize - m_nBufferPos && m_hFile != INVALID_HANDLE_VALUE)
  501.                 {
  502.                     if (!ReadFile(m_hFile, m_pBuffer+m_nBufferPos, m_nBufSize-m_nBufferPos, &numread, 0))
  503.                     {
  504.                         CloseHandle(m_hFile);
  505.                         m_hFile = INVALID_HANDLE_VALUE;
  506.                         Close();
  507.                         m_status = 3; //TODO: Better reason
  508.                         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  509.                         return;
  510.                     }
  511.  
  512.                     if (!numread)
  513.                     {
  514.                         CloseHandle(m_hFile);
  515.                         m_hFile = INVALID_HANDLE_VALUE;
  516.  
  517.                         if (!m_nBufferPos)
  518.                         {
  519.                             if (m_pGssLayer || m_pSslLayer)
  520.                                 if (!ShutDown() && GetLastError() == WSAEWOULDBLOCK)
  521.                                     return;
  522.                             m_status = 0;
  523.                             m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  524.                             Close();
  525.                             return;
  526.                         }
  527.                     }
  528.                     else
  529.                         m_currentFileOffset += numread;
  530.  
  531.                     numread += m_nBufferPos;
  532.                     m_nBufferPos = 0;
  533.                 }
  534.                 else
  535.                     numread = m_nBufferPos;
  536.                 m_nBufferPos = 0;
  537.  
  538.                 if (numread < m_nBufSize)
  539.                 {
  540.                     CloseHandle(m_hFile);
  541.                     m_hFile = INVALID_HANDLE_VALUE;
  542.                 }
  543.  
  544.                 int numsend = numread;
  545.                 int nLimit = m_pOwner->GetSpeedLimit(download);
  546.                 if (nLimit != -1 && GetState() != aborted && numsend > nLimit)
  547.                     numsend = nLimit;
  548.  
  549.                 if (!numsend)
  550.                 {
  551.                     m_nBufferPos = numread;
  552.                     return;
  553.                 }
  554.  
  555.                 int    numsent = Send(m_pBuffer, numsend);
  556.                 if (numsent==SOCKET_ERROR)
  557.                 {
  558.                     if (GetLastError()!=WSAEWOULDBLOCK)
  559.                     {
  560.                         CloseHandle(m_hFile);
  561.                         m_hFile = INVALID_HANDLE_VALUE;
  562.                         m_status=1;
  563.                         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  564.                         Close();
  565.                         return;
  566.                     }
  567.                     m_nBufferPos=numread;
  568.                     return;
  569.                 }
  570.                 else if ((unsigned int)numsent<numread)
  571.                 {
  572.                     memmove(m_pBuffer, m_pBuffer+numsent, numread-numsent);
  573.                     m_nBufferPos=numread-numsent;
  574.                 }
  575.  
  576.                 if (nLimit != -1 && GetState() != aborted)
  577.                     m_pOwner->m_SlQuotas[download].nTransferred += numsent;
  578.     
  579.                 ((CServerThread *)m_pOwner->m_pOwner)->IncSendCount(numsent);
  580.                 m_wasActiveSinceCheck = true;
  581.  
  582.                 //Check if there are other commands in the command queue.
  583.                 MSG msg;
  584.                 if (PeekMessage(&msg,0, 0, 0, PM_NOREMOVE))
  585.                 {
  586.                     TriggerEvent(FD_WRITE);
  587.                     return;
  588.                 }
  589.             }
  590.         }
  591.         if (m_pGssLayer || m_pSslLayer)
  592.             if (!ShutDown() && GetLastError() == WSAEWOULDBLOCK)
  593.                 return;
  594.         m_status = 0;
  595.         Sleep(0); //Give the system the possibility to relay the data
  596.                   //If not using Sleep(0), GetRight for example can't receive the last chunk.
  597.         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  598.         Close();
  599.     }
  600. }
  601.  
  602. void CTransferSocket::OnConnect(int nErrorCode)
  603. {
  604.     if (nErrorCode)
  605.     {
  606.         if (m_hFile!=INVALID_HANDLE_VALUE)
  607.         {
  608.             CloseHandle(m_hFile);
  609.             m_hFile = INVALID_HANDLE_VALUE;
  610.         }
  611.         Close();
  612.         if (!m_bSentClose)
  613.         {
  614.             m_bSentClose = TRUE;
  615.             m_status = 2;
  616.             m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  617.         }
  618.         return;
  619.     }
  620.  
  621.     int size = (int)m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_BUFFERSIZE2);
  622.     if (size > 0)
  623.     {
  624.         if (m_nMode == TRANSFERMODE_RECEIVE)
  625.             SetSockOpt(SO_RCVBUF, &size, sizeof(int));
  626.         else
  627.             SetSockOpt(SO_SNDBUF, &size, sizeof(int));
  628.     }
  629.  
  630.     if (m_pGssLayer)
  631.         VERIFY(AddLayer(m_pGssLayer));
  632.     if (m_pSslLayer)
  633.     {
  634.         VERIFY(AddLayer(m_pSslLayer));
  635.  
  636.         int code = m_pSslLayer->InitSSLConnection(false, m_sslContext);
  637.         if (code == SSL_FAILURE_LOADDLLS)
  638.             m_pOwner->SendStatus("Failed to load SSL libraries", 1);
  639.         else if (code == SSL_FAILURE_INITSSL)
  640.             m_pOwner->SendStatus("Failed to initialize SSL library", 1);
  641.         
  642.         if (code)
  643.         {
  644.             Close();
  645.             if (!m_bSentClose)
  646.             {
  647.                 m_bSentClose = TRUE;
  648.                 m_status = 2;
  649.                 m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  650.             }
  651.             return;
  652.         }
  653.     }
  654.  
  655.     if (!m_bStarted)
  656.         InitTransfer(FALSE);
  657.  
  658.     CAsyncSocketEx::OnConnect(nErrorCode);
  659. }
  660.  
  661. void CTransferSocket::OnClose(int nErrorCode)
  662. {
  663.     if (nErrorCode)
  664.     {
  665.         Close();
  666.         if (m_hFile)
  667.         {
  668.             FlushFileBuffers(m_hFile);
  669.             CloseHandle(m_hFile);
  670.             m_hFile = INVALID_HANDLE_VALUE;
  671.         }
  672.         if (!m_bSentClose)
  673.         {
  674.             m_bSentClose=TRUE;
  675.             m_status=1;
  676.             m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  677.         }
  678.         return;
  679.     }
  680.     if (m_bReady)
  681.     {
  682.         if (m_nMode==TRANSFERMODE_RECEIVE)
  683.         {
  684.             //Receive all data still waiting to be recieve
  685.             _int64 pos=0;
  686.             do
  687.             {
  688.                 if (m_hFile != INVALID_HANDLE_VALUE)
  689.                     pos=GetPosition64(m_hFile);
  690.                 OnReceive(0);
  691.                 if (m_hFile != INVALID_HANDLE_VALUE)
  692.                     if (pos == GetPosition64(m_hFile))
  693.                         break; //Leave loop when no data was written to file
  694.             } while (m_hFile != INVALID_HANDLE_VALUE); //Or file was closed
  695.             Close();
  696.             if (m_hFile != INVALID_HANDLE_VALUE)
  697.             {
  698.                 FlushFileBuffers(m_hFile);
  699.                 CloseHandle(m_hFile);
  700.                 m_hFile = INVALID_HANDLE_VALUE;
  701.             }
  702.             if (!m_bSentClose)
  703.             {
  704.                 m_bSentClose=TRUE;
  705.                 m_status=0;
  706.                 m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  707.             }
  708.         }
  709.         else
  710.         {
  711.             Close();
  712.             m_status=(m_nMode==TRANSFERMODE_RECEIVE)?0:1;
  713.             m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  714.         }
  715.     }
  716.  
  717.     CAsyncSocketEx::OnClose(nErrorCode);
  718. }
  719.  
  720. int CTransferSocket::GetStatus()
  721. {
  722.     return m_status;
  723. }
  724.  
  725. void CTransferSocket::OnAccept(int nErrorCode)
  726. {
  727.     CAsyncSocketEx tmp;
  728.     Accept(tmp);
  729.     SOCKET socket=tmp.Detach();
  730.     Close();
  731.     Attach(socket);
  732.     bAccepted=TRUE;
  733.  
  734.     int size = (int)m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_BUFFERSIZE2);
  735.     if (size > 0)
  736.     {
  737.         if (m_nMode == TRANSFERMODE_RECEIVE)
  738.             SetSockOpt(SO_RCVBUF, &size, sizeof(int));
  739.         else
  740.             SetSockOpt(SO_SNDBUF, &size, sizeof(int));
  741.     }
  742.  
  743.     if (m_pGssLayer)
  744.         VERIFY(AddLayer(m_pGssLayer));
  745.     if (m_pSslLayer)
  746.     {
  747.         VERIFY(AddLayer(m_pSslLayer));
  748.         
  749.         int code = m_pSslLayer->InitSSLConnection(false, m_sslContext);
  750.         if (code == SSL_FAILURE_LOADDLLS)
  751.             m_pOwner->SendStatus("Failed to load SSL libraries", 1);
  752.         else if (code == SSL_FAILURE_INITSSL)
  753.             m_pOwner->SendStatus("Failed to initialize SSL library", 1);
  754.         
  755.         if (code)
  756.         {
  757.             Close();
  758.             if (!m_bSentClose)
  759.             {
  760.                 m_bSentClose = TRUE;
  761.                 m_status = 2;
  762.                 m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  763.             }
  764.             return;
  765.         }
  766.     }
  767.  
  768.     if (m_bReady)
  769.         if (!m_bStarted)
  770.             InitTransfer(FALSE);
  771.  
  772.     CAsyncSocketEx::OnAccept(nErrorCode);
  773. }
  774.  
  775. void CTransferSocket::OnReceive(int nErrorCode)
  776. {
  777.     CAsyncSocketEx::OnReceive(nErrorCode);
  778.  
  779.     bool obeySpeedLimit = true;
  780.     if (nErrorCode == WSAESHUTDOWN)
  781.         obeySpeedLimit = false;
  782.     else if (nErrorCode)
  783.     {
  784.         Close();
  785.         if (m_hFile != INVALID_HANDLE_VALUE)
  786.         {
  787.             CloseHandle(m_hFile);
  788.             m_hFile = INVALID_HANDLE_VALUE;
  789.         }
  790.         if (!m_bSentClose)
  791.         {
  792.             m_bSentClose=TRUE;
  793.             m_status=3;
  794.             m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  795.         }
  796.         return;
  797.     }
  798.     else if (GetState() == closed)
  799.         obeySpeedLimit = false;
  800.  
  801.     if (m_nMode == TRANSFERMODE_RECEIVE)
  802.     {
  803.         if (!m_bStarted)
  804.             if (!InitTransfer(FALSE))
  805.                 return;
  806.  
  807.         m_wasActiveSinceCheck = true;
  808.  
  809.         int len = m_nBufSize;
  810.         int nLimit = -1;
  811.         if (obeySpeedLimit)
  812.         {
  813.             nLimit = m_pOwner->GetSpeedLimit(upload);
  814.             if (nLimit != -1 && GetState() != aborted && len > nLimit)
  815.                 len = nLimit;
  816.         }
  817.  
  818.         if (!len)
  819.             return;
  820.  
  821.         int numread = Receive(m_pBuffer, len);
  822.  
  823.         if (numread == SOCKET_ERROR)
  824.         {
  825.             if (GetLastError() != WSAEWOULDBLOCK)
  826.             {
  827.                 if (m_hFile!=INVALID_HANDLE_VALUE)
  828.                 {
  829.                     CloseHandle(m_hFile);
  830.                     m_hFile = INVALID_HANDLE_VALUE;
  831.                 }
  832.                 Close();
  833.                 if (!m_bSentClose)
  834.                 {
  835.                     m_bSentClose=TRUE;
  836.                     m_status=1;
  837.                     m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  838.                 }
  839.             }
  840.             Sleep(0);
  841.             return;
  842.         }
  843.         if (!numread)
  844.         {
  845.             if (m_hFile != INVALID_HANDLE_VALUE)
  846.             {
  847.                 CloseHandle(m_hFile);
  848.                 m_hFile = INVALID_HANDLE_VALUE;
  849.             }
  850.             Close();
  851.             if (!m_bSentClose)
  852.             {
  853.                 m_bSentClose=TRUE;
  854.                 m_status=0;
  855.                 m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  856.             }
  857.             return;
  858.         }
  859.         ((CServerThread *)m_pOwner->m_pOwner)->IncRecvCount(numread);
  860.  
  861.         if (nLimit != -1 && GetState() != aborted)
  862.             m_pOwner->m_SlQuotas[upload].nTransferred += numread;
  863.  
  864.         if (m_useZlib)
  865.         {
  866.             if (!m_pBuffer2)
  867.                 m_pBuffer2 = new char[m_nBufSize];
  868.  
  869.             m_zlibStream.next_in = (Bytef *)m_pBuffer;
  870.             m_zlibStream.avail_in = numread;
  871.             m_zlibStream.next_out = (Bytef *)m_pBuffer2;
  872.             m_zlibStream.avail_out = m_nBufSize;
  873.             
  874.             m_zlibStream.total_in = 0;
  875.             m_zlibStream.total_out = 0;
  876.             int res = inflate(&m_zlibStream, 0);
  877.             m_zlibBytesIn += m_zlibStream.total_in;
  878.             m_zlibBytesOut += m_zlibStream.total_out;
  879.             
  880.             while (res == Z_OK)
  881.             {
  882.                 DWORD numwritten;
  883.                 if (!WriteFile(m_hFile, m_pBuffer2, m_nBufSize - m_zlibStream.avail_out, &numwritten, 0) || numwritten != m_nBufSize - m_zlibStream.avail_out)
  884.                 {
  885.                     CloseHandle(m_hFile);
  886.                     m_hFile = INVALID_HANDLE_VALUE;
  887.                     Close();
  888.                     if (!m_bSentClose)
  889.                     {
  890.                         m_bSentClose=TRUE;
  891.                         m_status=3; //TODO: Better reason
  892.                         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  893.                     }
  894.                     return;
  895.                 }
  896.                 m_currentFileOffset += numwritten;
  897.  
  898.                 m_zlibStream.next_out = (Bytef *)m_pBuffer2;
  899.                 m_zlibStream.avail_out = m_nBufSize;
  900.                 res = inflate(&m_zlibStream, 0);
  901.             }
  902.             if (res == Z_STREAM_END)
  903.             {
  904.                 DWORD numwritten;
  905.                 if (!WriteFile(m_hFile, m_pBuffer2, m_nBufSize - m_zlibStream.avail_out, &numwritten, 0) || numwritten != m_nBufSize - m_zlibStream.avail_out)
  906.                 {
  907.                     CloseHandle(m_hFile);
  908.                     m_hFile = INVALID_HANDLE_VALUE;
  909.                     Close();
  910.                     if (!m_bSentClose)
  911.                     {
  912.                         m_bSentClose=TRUE;
  913.                         m_status=3; //TODO: Better reason
  914.                         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  915.                     }
  916.                     return;
  917.                 }
  918.                 m_currentFileOffset += numwritten;
  919.             }
  920.             else if (res != Z_OK && res != Z_BUF_ERROR)
  921.             {
  922.                 CloseHandle(m_hFile);
  923.                 m_hFile = INVALID_HANDLE_VALUE;
  924.                 Close();
  925.                 if (!m_bSentClose)
  926.                 {
  927.                     m_bSentClose=TRUE;
  928.                     m_status = 6;
  929.                     m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  930.                 }
  931.                 return;
  932.             }
  933.         }
  934.         else
  935.         {
  936.             DWORD numwritten;
  937.             if (!WriteFile(m_hFile, m_pBuffer, numread, &numwritten, 0) || numwritten!=(unsigned int)numread)
  938.             {
  939.                 CloseHandle(m_hFile);
  940.                 m_hFile = INVALID_HANDLE_VALUE;
  941.                 Close();
  942.                 if (!m_bSentClose)
  943.                 {
  944.                     m_bSentClose=TRUE;
  945.                     m_status=3; //TODO: Better reason
  946.                     m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  947.                 }
  948.                 return;
  949.             }
  950.             m_currentFileOffset += numwritten;
  951.         }
  952.     }
  953. }
  954.  
  955. void CTransferSocket::PasvTransfer()
  956. {
  957.     if(bAccepted)
  958.         if (!m_bStarted)
  959.             InitTransfer(FALSE);
  960. }
  961.  
  962. BOOL CTransferSocket::InitTransfer(BOOL bCalledFromSend)
  963. {
  964.     if (m_nMode==TRANSFERMODE_RECEIVE)
  965.     { //Uploads from client
  966.         if (!m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_INFXP))
  967.         { //Check if the IP of the remote machine is valid
  968.             CStdString OwnerIP,TransferIP;
  969.  
  970.             SOCKADDR_IN sockAddr;
  971.             memset(&sockAddr, 0, sizeof(sockAddr));
  972.             int nSockAddrLen = sizeof(sockAddr);
  973.             BOOL bResult = m_pOwner->GetSockName((SOCKADDR*)&sockAddr, &nSockAddrLen);
  974.             if (bResult)
  975.                 OwnerIP = inet_ntoa(sockAddr.sin_addr);
  976.  
  977.             memset(&sockAddr, 0, sizeof(sockAddr));
  978.             nSockAddrLen = sizeof(sockAddr);
  979.             bResult = GetSockName((SOCKADDR*)&sockAddr, &nSockAddrLen);
  980.             if (bResult)
  981.                 TransferIP = inet_ntoa(sockAddr.sin_addr);
  982.  
  983.             if (!m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_NOINFXPSTRICT))
  984.             {
  985.                 OwnerIP.Left(OwnerIP.ReverseFind('.'));
  986.                 TransferIP.Left(OwnerIP.ReverseFind('.'));
  987.             }
  988.             if (OwnerIP != TransferIP && OwnerIP != "127.0.0.1" && TransferIP != "127.0.0.1")
  989.             {
  990.                 m_status = 5;
  991.                 Close();
  992.                 m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  993.                 return FALSE;
  994.             }
  995.         }
  996.         AsyncSelect(FD_READ|FD_CLOSE);
  997.     }
  998.     else
  999.     { //Send files or directory listing to client
  1000.         if (!m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_OUTFXP))
  1001.         { //Check if remote IP is valid
  1002.             CStdString OwnerIP,TransferIP;
  1003.  
  1004.             SOCKADDR_IN sockAddr;
  1005.             memset(&sockAddr, 0, sizeof(sockAddr));
  1006.             int nSockAddrLen = sizeof(sockAddr);
  1007.             BOOL bResult = m_pOwner->GetSockName((SOCKADDR*)&sockAddr, &nSockAddrLen);
  1008.             if (bResult)
  1009.                 OwnerIP = inet_ntoa(sockAddr.sin_addr);
  1010.  
  1011.             memset(&sockAddr, 0, sizeof(sockAddr));
  1012.             nSockAddrLen = sizeof(sockAddr);
  1013.             bResult = GetSockName((SOCKADDR*)&sockAddr, &nSockAddrLen);
  1014.             if (bResult)
  1015.                 TransferIP = inet_ntoa(sockAddr.sin_addr);
  1016.  
  1017.             if (!m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_NOOUTFXPSTRICT))
  1018.             {
  1019.                 OwnerIP.Left(OwnerIP.ReverseFind('.'));
  1020.                 TransferIP.Left(OwnerIP.ReverseFind('.'));
  1021.             }
  1022.             if (OwnerIP != TransferIP && OwnerIP != "127.0.0.1" && TransferIP != "127.0.0.1")
  1023.             {
  1024.                 m_status = 5;
  1025.                 Close();
  1026.                 m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  1027.                 return FALSE;
  1028.             }
  1029.         }
  1030.         AsyncSelect(FD_WRITE|FD_CLOSE);
  1031.     }
  1032.  
  1033.     if (bAccepted)
  1034.     {
  1035.         CStdString str="150 Connection accepted";
  1036.         if (m_nRest)
  1037.             str.Format("150 Connection accepted, restarting at offset %I64d",m_nRest);
  1038.         m_pOwner->Send(str);
  1039.     }
  1040.  
  1041.     m_bStarted = TRUE;
  1042.     if (m_nMode == TRANSFERMODE_SEND)
  1043.     {
  1044.         ASSERT(m_Filename!="");
  1045.         m_hFile = CreateFile(m_Filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
  1046.         if (m_hFile == INVALID_HANDLE_VALUE)
  1047.         {
  1048.             m_status=3;
  1049.             m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  1050.             Close();
  1051.             return FALSE;
  1052.         }
  1053.         DWORD low=(DWORD)(m_nRest&0xFFFFFFFF);
  1054.         LONG high=(LONG)(m_nRest>>32);
  1055.         if ((low = SetFilePointer(m_hFile, low, &high, FILE_BEGIN)) == 0xFFFFFFFF && GetLastError() != NO_ERROR)
  1056.         {
  1057.             high = 0;
  1058.             low = SetFilePointer(m_hFile, 0, &high, FILE_END);
  1059.             if (low == 0xFFFFFFFF && GetLastError() != NO_ERROR)
  1060.             {
  1061.                 m_status=3;
  1062.                 m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  1063.                 Close();
  1064.                 return FALSE;
  1065.             }
  1066.         }
  1067.         m_currentFileOffset = (((__int64)high) << 32) + low;
  1068.  
  1069.         if (!m_pBuffer)
  1070.         {
  1071.             m_pBuffer = new char[m_nBufSize];
  1072.             m_nBufferPos = 0;
  1073.  
  1074.             if (m_useZlib)
  1075.             {
  1076.                 m_zlibStream.next_out = (Bytef *)m_pBuffer;
  1077.                 m_zlibStream.avail_out = m_nBufSize;
  1078.             }
  1079.         }
  1080.     }
  1081.     else if (m_nMode == TRANSFERMODE_RECEIVE)
  1082.     {
  1083.         unsigned int buflen = 0;
  1084.         int varlen = sizeof(buflen);
  1085.         if (GetSockOpt(SO_RCVBUF, &buflen, &varlen))
  1086.         {
  1087.             if (buflen < m_nBufSize)
  1088.             {
  1089.                 buflen = m_nBufSize;
  1090.                 SetSockOpt(SO_RCVBUF, &buflen, varlen);
  1091.             }
  1092.         }
  1093.  
  1094.         if (m_hFile == INVALID_HANDLE_VALUE)
  1095.         {
  1096.             ASSERT(m_Filename != "");
  1097.             m_hFile = CreateFile(m_Filename, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, 0, 0);
  1098.             if (m_hFile == INVALID_HANDLE_VALUE)
  1099.             {
  1100.                 Close();
  1101.                 if (!m_bSentClose)
  1102.                 {
  1103.                     m_bSentClose = TRUE;
  1104.                     m_status = 3;
  1105.                     m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  1106.                 }
  1107.                 return FALSE;
  1108.             }
  1109.             DWORD low = (DWORD)(m_nRest&0xFFFFFFFF);
  1110.             LONG high = (LONG)(m_nRest>>32);
  1111.             low = SetFilePointer(m_hFile, low, &high, FILE_BEGIN);
  1112.             if (low == 0xFFFFFFFF && GetLastError() != NO_ERROR)
  1113.             {
  1114.                 Close();
  1115.                 if (!m_bSentClose)
  1116.                 {
  1117.                     m_bSentClose = TRUE;
  1118.                     m_status = 3;
  1119.                     m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  1120.                 }
  1121.                 return FALSE;
  1122.             }
  1123.             SetEndOfFile(m_hFile);
  1124.             m_currentFileOffset = (((__int64)high) << 32) + low;
  1125.         }
  1126.  
  1127.         if (!m_pBuffer)
  1128.             m_pBuffer = new char[m_nBufSize];
  1129.     }
  1130.  
  1131.     GetSystemTime(&m_LastActiveTime);
  1132.     return TRUE;
  1133. }
  1134.  
  1135. BOOL CTransferSocket::CheckForTimeout()
  1136. {
  1137.     if (!m_bReady)
  1138.         return FALSE;
  1139.  
  1140.     _int64 timeout = m_pOwner->m_pOwner->m_pOptions->GetOptionVal(OPTION_TIMEOUT);
  1141.  
  1142.     SYSTEMTIME sCurrentTime;
  1143.     GetSystemTime(&sCurrentTime);
  1144.     FILETIME fCurrentTime;
  1145.     SystemTimeToFileTime(&sCurrentTime, &fCurrentTime);
  1146.     FILETIME fLastTime;
  1147.     if (m_wasActiveSinceCheck)
  1148.     {
  1149.         m_wasActiveSinceCheck = false;
  1150.         GetSystemTime(&m_LastActiveTime);
  1151.         return TRUE;
  1152.     }
  1153.  
  1154.     SystemTimeToFileTime(&m_LastActiveTime, &fLastTime);
  1155.     _int64 elapsed = ((_int64)(fCurrentTime.dwHighDateTime - fLastTime.dwHighDateTime) << 32) + fCurrentTime.dwLowDateTime - fLastTime.dwLowDateTime;
  1156.     if (timeout && elapsed > (timeout*10000000))
  1157.     {
  1158.         m_status=4;
  1159.         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  1160.     }
  1161.     else if (!m_bStarted && elapsed > (10 * 10000000))
  1162.     {
  1163.         m_status = 2;
  1164.         m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  1165.         return FALSE;
  1166.     }
  1167.     else if (!timeout)
  1168.         return FALSE;
  1169.  
  1170.     return TRUE;
  1171. }
  1172.  
  1173. BOOL CTransferSocket::Started() const
  1174. {
  1175.     return m_bStarted;
  1176. }
  1177.  
  1178. int CTransferSocket::GetMode() const
  1179. {
  1180.     return m_nMode;
  1181. }
  1182.  
  1183. void CTransferSocket::UseGSS(CAsyncGssSocketLayer *pGssLayer)
  1184. {
  1185.     m_pGssLayer = new CAsyncGssSocketLayer;
  1186.     m_pGssLayer->InitTransferChannel(pGssLayer);
  1187. }
  1188.  
  1189. void CTransferSocket::UseSSL(CAsyncSslSocketLayer *pSslLayer, void* sslContext)
  1190. {
  1191.     m_pSslLayer = pSslLayer;
  1192.     m_sslContext = sslContext;
  1193. }
  1194.  
  1195. int CTransferSocket::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
  1196. {
  1197.     for (std::list<t_callbackMsg>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++)
  1198.     {
  1199.         if (m_pGssLayer && iter->pLayer == m_pGssLayer)
  1200.         {
  1201.             if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC && iter->nParam1 == GSS_SHUTDOWN_COMPLETE)
  1202.             {
  1203.                 m_status = 0;
  1204.                 Sleep(0); //Give the system the possibility to relay the data
  1205.                 //If not using Sleep(0), GetRight for example can't receive the last chunk.
  1206.                 m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  1207.                 Close();
  1208.  
  1209.                 do
  1210.                 {
  1211.                     delete [] iter->str;
  1212.                     iter++;
  1213.                 } while (iter != callbacks.end());
  1214.  
  1215.                 return 0;
  1216.             }
  1217.         }
  1218.         else if (m_pSslLayer && iter->pLayer == m_pSslLayer)
  1219.         {
  1220.             if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC && iter->nParam1 == SSL_INFO && iter->nParam2 == SSL_INFO_SHUTDOWNCOMPLETE)
  1221.             {
  1222.                 m_status = 0;
  1223.                 Sleep(0); //Give the system the possibility to relay the data
  1224.                 //If not using Sleep(0), GetRight for example can't receive the last chunk.
  1225.                 m_pOwner->m_pOwner->PostThreadMessage(WM_FILEZILLA_THREADMSG, FTM_TRANSFERMSG, m_pOwner->m_userid);
  1226.                 Close();
  1227.  
  1228.                 do
  1229.                 {
  1230.                     delete [] iter->str;
  1231.                     iter++;
  1232.                 } while (iter != callbacks.end());
  1233.                 
  1234.                 return 0;
  1235.             }
  1236.             else if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC && iter->nParam1 == SSL_VERBOSE_WARNING)
  1237.             {
  1238.                 if (iter->str)
  1239.                 {
  1240.                     CStdString str = "Data connection SSL warning: ";
  1241.                     str += iter->str;
  1242.  
  1243.                     m_pOwner->SendStatus(str, 1);
  1244.                 }
  1245.             }
  1246.             /* Verbose info for debugging
  1247.             else if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC && iter->nParam1 == SSL_VERBOSE_INFO)
  1248.             {
  1249.                 if (iter->str)
  1250.                 {
  1251.                     CStdString str = "SSL info: ";
  1252.                     str += iter->str;
  1253.  
  1254.                     m_pOwner->SendStatus(str, 0);
  1255.                 }
  1256.             }*/
  1257.             else if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC && iter->nParam1 == SSL_INFO_ESTABLISHED)
  1258.             {
  1259.                 m_pOwner->SendStatus("SSL connection for data connection established", 0);
  1260.                 return 0;
  1261.             }
  1262.         }
  1263.         delete [] iter->str;
  1264.     }
  1265.     return 0;
  1266. }
  1267.  
  1268. bool CTransferSocket::InitZLib(int level)
  1269. {
  1270.     int res;
  1271.     if (m_nMode == TRANSFERMODE_RECEIVE)
  1272.         res = inflateInit2(&m_zlibStream, 15);
  1273.     else
  1274.         res = deflateInit2(&m_zlibStream, level, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY);
  1275.     
  1276.     if (res == Z_OK)
  1277.         m_useZlib = true;
  1278.  
  1279.     return res == Z_OK;
  1280. }
  1281.  
  1282. bool CTransferSocket::GetZlibStats(_int64 &bytesIn, _int64 &bytesOut) const
  1283. {
  1284.     bytesIn = m_zlibBytesIn;
  1285.     bytesOut = m_zlibBytesOut;
  1286.     
  1287.     return true;
  1288. }
  1289.