| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 | //---------------------------------------------------------------------------#include "stdafx.h"#include "MainThread.h"#define ECS m_CriticalSection.Lock()#define LCS m_CriticalSection.Unlock()/////////////////////////////////////////////////////////////////////////////// CMainThreadCMainThread::CMainThread(){  m_pTools = NULL;  m_nInternalMessageID = 0;  m_pPostKeepAliveCommand = 0;  m_nTimerID = 0;  m_pControlSocket = NULL;  m_bBusy = FALSE;  m_bConnected = FALSE;  m_pWorkingDir = 0;  m_nAsyncRequestID = 0;  m_bQuit = FALSE;  m_hThread = 0;  m_dwThreadId = 0;}CMainThread::~CMainThread(){  delete m_pWorkingDir;  CloseHandle(m_hThread);}BOOL CMainThread::InitInstance(){  m_nTimerID=SetTimer(0,1,1000,0);  m_pPostKeepAliveCommand=0;  // initialize Winsock library  BOOL res=TRUE;  WSADATA wsaData;  WORD wVersionRequested = MAKEWORD(1, 1);  int nResult = WSAStartup(wVersionRequested, &wsaData);  if (nResult != 0)    res=FALSE;  else if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)  {    WSACleanup();    res=FALSE;  }  m_pControlSocket=new CFtpControlSocket(this, m_pTools);  m_pControlSocket->InitIntern(GetIntern());  return TRUE;}DWORD CMainThread::ExitInstance(){  KillTimer(0,m_nTimerID);  if (m_pControlSocket)    delete m_pControlSocket;  return 1;}BOOL CMainThread::IsConnected(){  BOOL bConnected;  ECS;  bConnected=m_bConnected;  LCS;  return bConnected;}void CMainThread::OnTimer(WPARAM wParam, LPARAM lParam){  if (!m_pControlSocket)    return;  if (wParam==m_nTimerID)    m_pControlSocket->OnTimer();  return;}BOOL CMainThread::OnThreadMessage(UINT Msg, WPARAM wParam, LPARAM lParam){  if (Msg==m_nInternalMessageID)  {    if (wParam==FZAPI_THREADMSG_COMMAND)    {      if (m_pControlSocket && !m_pControlSocket->IsReady())        m_pPostKeepAliveCommand=(t_command *)lParam;      else      {        t_command *pCommand=(t_command *)lParam;        switch(pCommand->id)        {        case FZ_COMMAND_CONNECT:          DebugAssert(!IsConnected());          SetCurrentPath(CServerPath());          m_pControlSocket->Connect(pCommand->server);          break;        case FZ_COMMAND_LIST:          DebugAssert(m_pControlSocket);          m_pControlSocket->List(FALSE, 0, pCommand->path, pCommand->param1);          break;        case FZ_COMMAND_LISTFILE:          DebugAssert(m_pControlSocket);          m_pControlSocket->ListFile(pCommand->param1, pCommand->path);          break;        case FZ_COMMAND_FILETRANSFER:          DebugAssert(m_pControlSocket);          m_pControlSocket->FileTransfer(&pCommand->transferfile);          break;        case FZ_COMMAND_CUSTOMCOMMAND:          DebugAssert(m_pControlSocket);          m_pControlSocket->FtpCommand(pCommand->param1);          break;        case FZ_COMMAND_DELETE:          DebugAssert(m_pControlSocket);          m_pControlSocket->Delete(pCommand->param1, pCommand->path, (pCommand->param4 != 0));          break;        case FZ_COMMAND_REMOVEDIR:          DebugAssert(m_pControlSocket);          m_pControlSocket->RemoveDir(pCommand->param1, pCommand->path);          break;        case FZ_COMMAND_MAKEDIR:          DebugAssert(m_pControlSocket);          m_pControlSocket->MakeDir(pCommand->path);          break;        case FZ_COMMAND_RENAME:          DebugAssert(m_pControlSocket);          m_pControlSocket->Rename(pCommand->param1, pCommand->param2, pCommand->path, pCommand->newPath);          break;        case FZ_COMMAND_CHMOD:          DebugAssert(m_pControlSocket);          m_pControlSocket->Chmod(pCommand->param1, pCommand->path, pCommand->param4);          break;        }        delete pCommand;      }    }    else if (wParam==FZAPI_THREADMSG_PROCESSREPLY)      m_pControlSocket->ProcessReply();    else if (wParam==FZAPI_THREADMSG_TRANSFEREND)      m_pControlSocket->TransferEnd(lParam);    else if (wParam==FZAPI_THREADMSG_CANCEL)      m_pControlSocket->Cancel(lParam);    else if (wParam==FZAPI_THREADMSG_DISCONNECT)      m_pControlSocket->Disconnect();    else if (wParam==FZAPI_THREADMSG_POSTKEEPALIVE)    {      if (m_pPostKeepAliveCommand)      {        PostThreadMessage(m_nInternalMessageID,FZAPI_THREADMSG_COMMAND,(LPARAM)m_pPostKeepAliveCommand);        m_pPostKeepAliveCommand=0;      }    }    else if (wParam==FZAPI_THREADMSG_ASYNCREQUESTREPLY)    {      CAsyncRequestData *pData=(CAsyncRequestData *)lParam;      if (pData)      {        if (pData->nRequestID!=GetAsyncRequestID())          LogMessage(FZ_LOG_INFO, L"Ignoring old request ID");        else          m_pControlSocket->SetAsyncRequestResult(pData->nRequestResult, pData);        delete pData;      }      else        LogMessage(FZ_LOG_WARNING, L"Request reply without data");    }    return TRUE;  }  else if (Msg==WM_TIMER)  {    OnTimer(wParam, lParam);  }  return TRUE;}BOOL CMainThread::IsBusy(){  BOOL bBusy;  ECS;  bBusy=m_bBusy;  LCS;  return bBusy;}void CMainThread::Command(const t_command &command){  DebugAssert(!IsBusy());  ECS;  if (m_bQuit)  {    LCS;    return;  }  m_bBusy=TRUE;  t_command *pCommand=new t_command;  *pCommand=command;  DebugCheck(PostThreadMessage(m_nInternalMessageID,FZAPI_THREADMSG_COMMAND,(LPARAM)pCommand));  m_LastCommand=command;  LCS;}BOOL CMainThread::LastOperationSuccessful(){  return TRUE;}void CMainThread::SetBusy(BOOL bBusy){  ECS;  m_bBusy=bBusy;  LCS;}void CMainThread::SetConnected(BOOL bConnected /*=TRUE*/){  ECS;  m_bConnected=bConnected;  if (!bConnected)  {    // when we loose connection    // reset pending commands as we cannot fulfill them anyway    m_pPostKeepAliveCommand = 0;  }  LCS;}bool CMainThread::GetCurrentPath(CServerPath &dir){  if (!IsConnected())    return false;  ECS;  dir=m_CurrentPath;  LCS;  return true;}CServerPath CMainThread::GetCurrentPath(){  CServerPath path;  bool res = GetCurrentPath(path);  if (!res)    return CServerPath();  return path;}BOOL CMainThread::GetCurrentServer(t_server &server){  if (!IsConnected())    return FALSE;  ECS;  server=m_pControlSocket->GetCurrentServer();  LCS;  return TRUE;}void CMainThread::Quit(){  ECS;  m_bQuit=TRUE;  LCS;  if (IsBusy())    PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_CANCEL, 1);  PostThreadMessage(WM_QUIT, 0, 0);}void CMainThread::SetCurrentPath(CServerPath path){  ECS;  m_CurrentPath=path;  LCS;  return;}bool CMainThread::UsingMlsd(){  if (!IsConnected())    return false;  return m_pControlSocket->UsingMlsd();}bool CMainThread::UsingUtf8(){  if (!IsConnected())    return false;  return m_pControlSocket->UsingUtf8();}std::string CMainThread::GetTlsVersionStr(){  if (!IsConnected())    return std::string();  return m_pControlSocket->GetTlsVersionStr();}std::string CMainThread::GetCipherName(){  if (!IsConnected())    return std::string();  return m_pControlSocket->GetCipherName();}BOOL CMainThread::GetWorkingDir(t_directory *pWorkingDir){  ECS;  if (m_pWorkingDir)  {    *pWorkingDir=*m_pWorkingDir;    LCS;    return TRUE;  }  LCS;  return FALSE;}void CMainThread::SetWorkingDir(t_directory *pWorkingDir){  if (!pWorkingDir)  {    ECS;    delete m_pWorkingDir;    m_pWorkingDir=0;    LCS;  }  else  {    ECS;    if (!m_pWorkingDir)      m_pWorkingDir=new t_directory;    *m_pWorkingDir=*pWorkingDir;    LCS;  }  if (pWorkingDir)  {    t_directory *pDirectoryToSend=new t_directory;    *pDirectoryToSend=*pWorkingDir;    SendDirectoryListing(pDirectoryToSend);  }  return;}void CMainThread::SendDirectoryListing(t_directory * pDirectoryToSend){  if (!GetIntern()->PostMessage(FZ_MSG_MAKEMSG(FZ_MSG_LISTDATA, 0), (LPARAM)pDirectoryToSend))  {    delete pDirectoryToSend;  }}__int64 CMainThread::GetAsyncRequestID() const{  return m_nAsyncRequestID;}__int64 CMainThread::GetNextAsyncRequestID(){  return ++m_nAsyncRequestID;}CMainThread* CMainThread::Create(int nPriority, DWORD dwCreateFlags){  CMainThread *pMainThread=new CMainThread();  pMainThread->m_hThread=CreateThread(0, 0, ThreadProc, pMainThread, dwCreateFlags, &pMainThread->m_dwThreadId);  if (!pMainThread->m_hThread)  {    delete pMainThread;    return NULL;  }  ::SetThreadPriority(pMainThread->m_hThread, nPriority);  return pMainThread;}BOOL CMainThread::PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam){  return ::PostThreadMessage(m_dwThreadId, message, wParam, lParam);}DWORD CMainThread::ResumeThread(){  BOOL res=::ResumeThread(m_hThread);  if (res)  {    m_EventStarted.Lock();    m_EventStarted.Unlock();  }  return res;}DWORD WINAPI CMainThread::ThreadProc(LPVOID lpParameter){  return ((CMainThread *)lpParameter)->Run();}DWORD CMainThread::Run(){  ECS;  InitInstance();  m_EventStarted.SetEvent();  LCS;  MSG msg;  while (GetMessage(&msg, 0, 0, 0))  {    TranslateMessage(&msg);    if (!msg.hwnd)    {      OnThreadMessage(msg.message, msg.wParam, msg.lParam);    }    DispatchMessage(&msg);  }  DWORD res = ExitInstance();  delete this;  return res;}
 |