FileZillaApi.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. // FileZilla - a Windows ftp client
  2. // Copyright (C) 2002-2004 - Tim Kosse <[email protected]>
  3. // This program is free software; you can redistribute it and/or
  4. // modify it under the terms of the GNU General Public License
  5. // as published by the Free Software Foundation; either version 2
  6. // of the License, or (at your option) any later version.
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU General Public License for more details.
  11. // You should have received a copy of the GNU General Public License
  12. // along with this program; if not, write to the Free Software
  13. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. // FileZillaApi.cpp: Implementierung der Klasse CFileZillaApi.
  15. //
  16. //////////////////////////////////////////////////////////////////////
  17. #include "stdafx.h"
  18. #include "FileZillaApi.h"
  19. #include "mainthread.h"
  20. #ifndef MPEXT_NO_CACHE
  21. #include "directorycache.h"
  22. #endif
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static char THIS_FILE[]=__FILE__;
  26. #define new DEBUG_NEW
  27. #endif
  28. //////////////////////////////////////////////////////////////////////
  29. // Konstruktion/Destruktion
  30. //////////////////////////////////////////////////////////////////////
  31. CFileZillaApi::CFileZillaApi()
  32. {
  33. m_hOwnerWnd=0;
  34. #ifndef MPEXT
  35. //Create Message IDs
  36. m_nReplyMessageID=RegisterWindowMessage( _T("FileZillaApiReplyMessage{8EF2E328-685E-4815-A9B9-823512F8381D}") );
  37. #else
  38. m_nReplyMessageID=0;
  39. #endif
  40. m_nInternalMessageID=0;
  41. m_pMainThread=0;
  42. m_bInitialized=FALSE;
  43. }
  44. CFileZillaApi::~CFileZillaApi()
  45. {
  46. Destroy();
  47. }
  48. #ifndef MPEXT
  49. int CFileZillaApi::Init(HWND hOwnerWnd, int nReplyMessageID /*=0*/)
  50. #else
  51. int CFileZillaApi::Init(CApiLog * pParent, CFileZillaTools * pTools)
  52. #endif
  53. {
  54. //Check parameters
  55. //-> No check needed, if hOwnerWnd is NULL, use blocking mode and don't send status messages
  56. //Check if call allowed
  57. if (m_bInitialized)
  58. return FZ_REPLY_ALREADYINIZIALIZED;
  59. //Initialize variables
  60. #ifndef MPEXT
  61. if (nReplyMessageID)
  62. m_nReplyMessageID=nReplyMessageID;
  63. m_hOwnerWnd=hOwnerWnd;
  64. #endif
  65. m_nInternalMessageID=RegisterWindowMessage( _T("FileZillaInternalApiMessage{F958620E-040C-4b33-A091-7E04E10AA660}") );
  66. if (!m_nInternalMessageID)
  67. return FZ_REPLY_NOTINITIALIZED;
  68. //Create thread object
  69. m_pMainThread = CMainThread::Create(THREAD_PRIORITY_BELOW_NORMAL, CREATE_SUSPENDED);
  70. //Initialize Thread variables
  71. m_pMainThread->m_nInternalMessageID=m_nInternalMessageID;
  72. m_pMainThread->m_nReplyMessageID=m_nReplyMessageID;
  73. m_pMainThread->m_hOwnerWnd=m_hOwnerWnd;
  74. m_pMainThread->m_pTools=pTools;
  75. #ifndef MPEXT
  76. m_pMainThread->InitLog(m_hOwnerWnd, m_nReplyMessageID);
  77. #else
  78. m_pMainThread->InitLog(pParent);
  79. #endif
  80. //Resume Thread
  81. m_pMainThread->ResumeThread();
  82. //Initialization OK
  83. m_bInitialized=TRUE;
  84. return FZ_REPLY_OK;
  85. }
  86. unsigned int CFileZillaApi::GetMessageID()
  87. {
  88. return m_nReplyMessageID;
  89. }
  90. int CFileZillaApi::IsConnected()
  91. {
  92. if (!m_bInitialized)
  93. return FZ_REPLY_NOTINITIALIZED;
  94. return m_pMainThread->IsConnected()?FZ_REPLY_OK:FZ_REPLY_NOTCONNECTED;
  95. }
  96. int CFileZillaApi::IsBusy()
  97. {
  98. if (!m_bInitialized)
  99. return FZ_REPLY_NOTINITIALIZED;
  100. return m_pMainThread->IsBusy()?FZ_REPLY_BUSY:FZ_REPLY_IDLE;
  101. }
  102. int CFileZillaApi::Connect(const t_server &server)
  103. {
  104. //Check parameters
  105. if (server.host==_MPT("") || server.port<1 || server.port>65535)
  106. return FZ_REPLY_INVALIDPARAM;
  107. #ifndef MPEXT_NO_GSS
  108. BOOL bUseGSS = FALSE;
  109. if (COptions::GetOptionVal(OPTION_USEGSS))
  110. {
  111. USES_CONVERSION;
  112. CString GssServers = COptions::GetOption(OPTION_GSSSERVERS);
  113. hostent *fullname = gethostbyname(T2CA(server.host));
  114. CString host;
  115. if (fullname)
  116. host = fullname->h_name;
  117. else
  118. host = server.host;
  119. host.MakeLower();
  120. int i;
  121. while ((i=GssServers.Find( _T(";") ))!=-1)
  122. {
  123. if ((_MPT(".")+GssServers.Left(i))==host.Right(GssServers.Left(i).GetLength()+1) || GssServers.Left(i)==host)
  124. {
  125. bUseGSS = TRUE;
  126. break;
  127. }
  128. GssServers = GssServers.Mid(i+1);
  129. }
  130. }
  131. if (!bUseGSS && server.user == _MPT(""))
  132. return FZ_REPLY_INVALIDPARAM;
  133. #endif
  134. if (!(server.nServerType&FZ_SERVERTYPE_HIGHMASK))
  135. return FZ_REPLY_INVALIDPARAM;
  136. //Check if call allowed
  137. if (!m_bInitialized)
  138. return FZ_REPLY_NOTINITIALIZED;
  139. if (m_pMainThread->IsBusy())
  140. return FZ_REPLY_BUSY;
  141. t_command command;
  142. command.id=FZ_COMMAND_CONNECT;
  143. command.server=server;
  144. m_pMainThread->Command(command);
  145. if (m_hOwnerWnd)
  146. return FZ_REPLY_WOULDBLOCK;
  147. else
  148. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  149. }
  150. int CFileZillaApi::List(int nListMode /*=FZ_LIST_USECACHE*/)
  151. {
  152. //Check if call allowed
  153. if (!m_bInitialized)
  154. return FZ_REPLY_NOTINITIALIZED;
  155. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  156. return FZ_REPLY_NOTCONNECTED;
  157. if (nListMode&FZ_LIST_REALCHANGE)
  158. return FZ_REPLY_INVALIDPARAM;
  159. #ifndef MPEXT_NO_CACHE
  160. if (nListMode&FZ_LIST_FORCECACHE)
  161. nListMode|=FZ_LIST_USECACHE;
  162. //Check if current dir is cached
  163. CServerPath path;
  164. if (nListMode&FZ_LIST_USECACHE)
  165. {
  166. if (!m_pMainThread->GetWorkingDirPath(path) || path.IsEmpty())
  167. m_pMainThread->GetCurrentPath(path);
  168. if (!path.IsEmpty())
  169. {
  170. t_server server;
  171. BOOL res=m_pMainThread->GetCurrentServer(server);
  172. if (res)
  173. {
  174. t_directory *directory=new t_directory;
  175. CDirectoryCache cache;
  176. res=cache.Lookup(path,server,*directory);
  177. if (res)
  178. {
  179. BOOL bExact=TRUE;
  180. if (nListMode & FZ_LIST_EXACT)
  181. for (int i=0;i<directory->num;i++)
  182. if (directory->direntry[i].bUnsure || (directory->direntry[i].size==-1 && !directory->direntry[i].dir))
  183. {
  184. bExact=FALSE;
  185. break;
  186. }
  187. if (bExact)
  188. {
  189. m_pMainThread->SetWorkingDir(directory);
  190. delete directory;
  191. return FZ_REPLY_OK;
  192. }
  193. }
  194. delete directory;
  195. }
  196. }
  197. }
  198. #else
  199. CServerPath path;
  200. // seems to be incorrectly skipped when cache is not required
  201. if (!m_pMainThread->GetWorkingDirPath(path) || path.IsEmpty())
  202. m_pMainThread->GetCurrentPath(path);
  203. #endif
  204. if (m_pMainThread->IsBusy())
  205. return FZ_REPLY_BUSY;
  206. #ifndef MPEXT_NO_CACHE
  207. if (nListMode&FZ_LIST_FORCECACHE)
  208. return FZ_REPLY_ERROR;
  209. #endif
  210. t_command command;
  211. command.id=FZ_COMMAND_LIST;
  212. command.path = path;
  213. command.param4=nListMode;
  214. m_pMainThread->Command(command);
  215. if (m_hOwnerWnd)
  216. return FZ_REPLY_WOULDBLOCK;
  217. else
  218. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  219. }
  220. int CFileZillaApi::Cancel()
  221. {
  222. //Check if call allowed
  223. if (!m_bInitialized)
  224. return FZ_REPLY_NOTINITIALIZED;
  225. if (IsBusy()!=FZ_REPLY_BUSY)
  226. return FZ_REPLY_NOTBUSY;
  227. m_pMainThread->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_CANCEL, 0);
  228. return FZ_REPLY_WOULDBLOCK;
  229. }
  230. void CFileZillaApi::Destroy()
  231. {
  232. if (!m_bInitialized)
  233. return;
  234. ASSERT(m_pMainThread);
  235. HANDLE tmp=m_pMainThread->m_hThread;
  236. m_pMainThread->Quit();
  237. //Wait for the main thread to quit
  238. WaitForSingleObject(tmp, 10000);
  239. #ifndef MPEXT
  240. PostMessage(m_hOwnerWnd, m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_QUITCOMPLETE, 0), 0);
  241. #endif
  242. m_pMainThread=0;
  243. m_bInitialized=FALSE;
  244. }
  245. int CFileZillaApi::Disconnect()
  246. {
  247. //Check if call allowed
  248. if (!m_bInitialized)
  249. return FZ_REPLY_NOTINITIALIZED;
  250. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  251. return FZ_REPLY_NOTCONNECTED;
  252. if (IsBusy()==FZ_REPLY_BUSY)
  253. return FZ_REPLY_BUSY;
  254. m_pMainThread->PostThreadMessage(m_nInternalMessageID,FZAPI_THREADMSG_DISCONNECT,0);
  255. return FZ_REPLY_WOULDBLOCK;
  256. }
  257. int CFileZillaApi::Command(t_command *pCommand)
  258. {
  259. //Check if call allowed
  260. if (!m_bInitialized)
  261. return FZ_REPLY_NOTINITIALIZED;
  262. //Dispatch command to command specific functions
  263. switch(pCommand->id)
  264. {
  265. case FZ_COMMAND_LIST:
  266. if (pCommand->param1!=_MPT(""))
  267. return List(pCommand->path,pCommand->param1,pCommand->param4);
  268. else if (!pCommand->path.IsEmpty())
  269. return List(pCommand->path,pCommand->param4);
  270. else
  271. return List(pCommand->param4);
  272. break;
  273. case FZ_COMMAND_CONNECT:
  274. return Connect(pCommand->server);
  275. break;
  276. case FZ_COMMAND_DISCONNECT:
  277. return Disconnect();
  278. break;
  279. case FZ_COMMAND_FILETRANSFER:
  280. return FileTransfer(pCommand->transferfile);
  281. break;
  282. case FZ_COMMAND_DELETE:
  283. return Delete(pCommand->param1, pCommand->path);
  284. break;
  285. case FZ_COMMAND_REMOVEDIR:
  286. return RemoveDir(pCommand->param1, pCommand->path);
  287. break;
  288. case FZ_COMMAND_MAKEDIR:
  289. return MakeDir(pCommand->path);
  290. break;
  291. case FZ_COMMAND_RENAME:
  292. return Rename(pCommand->param1, pCommand->param2, pCommand->path, pCommand->newPath);
  293. break;
  294. case FZ_COMMAND_CUSTOMCOMMAND:
  295. return CustomCommand(pCommand->param1);
  296. break;
  297. case FZ_COMMAND_CHMOD:
  298. return Chmod(pCommand->param4, pCommand->param1, pCommand->path);
  299. break;
  300. }
  301. return FZ_REPLY_INVALIDPARAM;
  302. }
  303. int CFileZillaApi::List(const CServerPath& path, int nListMode /*=FZ_LIST_USECACHE*/)
  304. {
  305. //Check if call allowed
  306. if (!m_bInitialized)
  307. return FZ_REPLY_NOTINITIALIZED;
  308. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  309. return FZ_REPLY_NOTCONNECTED;
  310. #ifndef MPEXT_NO_CACHE
  311. if ( (nListMode&(FZ_LIST_FORCECACHE|FZ_LIST_REALCHANGE))==(FZ_LIST_FORCECACHE|FZ_LIST_REALCHANGE) )
  312. return FZ_REPLY_INVALIDPARAM;
  313. if (nListMode&FZ_LIST_FORCECACHE)
  314. nListMode|=FZ_LIST_USECACHE;
  315. #endif
  316. if (path.IsEmpty())
  317. return FZ_REPLY_INVALIDPARAM;
  318. #ifndef MPEXT_NO_CACHE
  319. //Check if current dir is cached
  320. if (nListMode&FZ_LIST_USECACHE && !(nListMode&FZ_LIST_REALCHANGE))
  321. {
  322. t_server server;
  323. BOOL res=m_pMainThread->GetCurrentServer(server);
  324. if (res)
  325. {
  326. t_directory *directory=new t_directory;
  327. CDirectoryCache cache;
  328. res=cache.Lookup(path,server,*directory);
  329. if (res)
  330. {
  331. BOOL bExact=TRUE;
  332. if (nListMode & FZ_LIST_EXACT)
  333. for (int i=0;i<directory->num;i++)
  334. if (directory->direntry[i].bUnsure || (directory->direntry[i].size==-1 && !directory->direntry[i].dir))
  335. {
  336. bExact=FALSE;
  337. break;
  338. }
  339. if (bExact)
  340. {
  341. m_pMainThread->SetWorkingDir(directory);
  342. delete directory;
  343. return FZ_REPLY_OK;
  344. }
  345. }
  346. delete directory;
  347. }
  348. }
  349. #endif
  350. if (m_pMainThread->IsBusy())
  351. return FZ_REPLY_BUSY;
  352. #ifndef MPEXT_NO_CACHE
  353. if (nListMode&FZ_LIST_FORCECACHE)
  354. return FZ_REPLY_ERROR;
  355. #endif
  356. t_command command;
  357. command.id=FZ_COMMAND_LIST;
  358. command.path=path;
  359. command.param4=nListMode;
  360. m_pMainThread->Command(command);
  361. if (m_hOwnerWnd)
  362. return FZ_REPLY_WOULDBLOCK;
  363. else
  364. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  365. }
  366. int CFileZillaApi::List(const CServerPath& parent, CString dirname, int nListMode /*=FZ_LIST_USECACHE*/)
  367. {
  368. //Check if call allowed
  369. if (!m_bInitialized)
  370. return FZ_REPLY_NOTINITIALIZED;
  371. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  372. return FZ_REPLY_NOTCONNECTED;
  373. #ifndef MPEXT_NO_CACHE
  374. if ( (nListMode&(FZ_LIST_FORCECACHE|FZ_LIST_REALCHANGE))==(FZ_LIST_FORCECACHE|FZ_LIST_REALCHANGE) )
  375. return FZ_REPLY_INVALIDPARAM;
  376. if (nListMode&FZ_LIST_FORCECACHE)
  377. nListMode|=FZ_LIST_USECACHE;
  378. #endif
  379. if (dirname==_MPT("") || parent.IsEmpty())
  380. return FZ_REPLY_INVALIDPARAM;
  381. #ifndef MPEXT_NO_CACHE
  382. //Check if current dir is cached
  383. if (nListMode&FZ_LIST_USECACHE && !(nListMode&FZ_LIST_REALCHANGE))
  384. {
  385. t_server server;
  386. BOOL res=m_pMainThread->GetCurrentServer(server);
  387. if (res)
  388. {
  389. t_directory *directory=new t_directory;
  390. CDirectoryCache cache;
  391. res=cache.Lookup(parent,dirname,server,*directory);
  392. if (res)
  393. {
  394. BOOL bExact=TRUE;
  395. if (nListMode & FZ_LIST_EXACT)
  396. for (int i=0;i<directory->num;i++)
  397. if (directory->direntry[i].bUnsure || (directory->direntry[i].size==-1 && !directory->direntry[i].dir))
  398. {
  399. bExact=FALSE;
  400. break;
  401. }
  402. if (bExact)
  403. {
  404. m_pMainThread->SetWorkingDir(directory);
  405. delete directory;
  406. return FZ_REPLY_OK;
  407. }
  408. }
  409. delete directory;
  410. }
  411. }
  412. #endif
  413. if (m_pMainThread->IsBusy())
  414. return FZ_REPLY_BUSY;
  415. #ifndef MPEXT_NO_CACHE
  416. if (nListMode&FZ_LIST_FORCECACHE)
  417. return FZ_REPLY_ERROR;
  418. #endif
  419. t_command command;
  420. command.id=FZ_COMMAND_LIST;
  421. command.path=parent;
  422. command.param1=dirname;
  423. command.param4=nListMode;
  424. m_pMainThread->Command(command);
  425. if (m_hOwnerWnd)
  426. return FZ_REPLY_WOULDBLOCK;
  427. else
  428. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  429. }
  430. #ifdef MPEXT
  431. int CFileZillaApi::ListFile(const CServerPath& path, const CString& fileName)
  432. {
  433. //Check if call allowed
  434. if (!m_bInitialized)
  435. return FZ_REPLY_NOTINITIALIZED;
  436. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  437. return FZ_REPLY_NOTCONNECTED;
  438. if (fileName.IsEmpty())
  439. return FZ_REPLY_INVALIDPARAM;
  440. if (m_pMainThread->IsBusy())
  441. return FZ_REPLY_BUSY;
  442. t_command command;
  443. command.id=FZ_COMMAND_LISTFILE;
  444. command.path=path;
  445. command.param1=fileName;
  446. m_pMainThread->Command(command);
  447. if (m_hOwnerWnd)
  448. return FZ_REPLY_WOULDBLOCK;
  449. else
  450. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  451. }
  452. #endif
  453. int CFileZillaApi::FileTransfer(const t_transferfile &TransferFile)
  454. {
  455. //Check if call allowed
  456. if (!m_bInitialized)
  457. return FZ_REPLY_NOTINITIALIZED;
  458. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  459. return FZ_REPLY_NOTCONNECTED;
  460. if (TransferFile.remotefile==_MPT("") || TransferFile.localfile==_MPT("") || TransferFile.remotepath.IsEmpty())
  461. return FZ_REPLY_INVALIDPARAM;
  462. if (IsBusy()==FZ_REPLY_BUSY)
  463. return FZ_REPLY_BUSY;
  464. t_command command;
  465. command.id=FZ_COMMAND_FILETRANSFER;
  466. command.transferfile=TransferFile;
  467. m_pMainThread->Command(command);
  468. if (m_hOwnerWnd)
  469. return FZ_REPLY_WOULDBLOCK;
  470. else
  471. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  472. }
  473. int CFileZillaApi::GetCurrentServer(t_server &server)
  474. {
  475. //Check if call allowed
  476. if (!m_bInitialized)
  477. return FZ_REPLY_NOTINITIALIZED;
  478. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  479. return FZ_REPLY_NOTCONNECTED;
  480. if (m_pMainThread->GetCurrentServer(server))
  481. return FZ_REPLY_OK;
  482. else
  483. return FZ_REPLY_NOTCONNECTED;
  484. }
  485. #ifdef MPEXT
  486. int CFileZillaApi::SetCurrentPath(CServerPath path)
  487. {
  488. //Check if call allowed
  489. if (!m_bInitialized)
  490. return FZ_REPLY_NOTINITIALIZED;
  491. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  492. return FZ_REPLY_NOTCONNECTED;
  493. m_pMainThread->SetCurrentPath(path);
  494. return FZ_REPLY_OK;
  495. }
  496. int CFileZillaApi::GetCurrentPath(CServerPath & path)
  497. {
  498. //Check if call allowed
  499. if (!m_bInitialized)
  500. return FZ_REPLY_NOTINITIALIZED;
  501. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  502. return FZ_REPLY_NOTCONNECTED;
  503. return (m_pMainThread->GetCurrentPath(path) ? FZ_REPLY_OK : FZ_REPLY_NOTCONNECTED);
  504. }
  505. bool CFileZillaApi::UsingMlsd()
  506. {
  507. //Check if call allowed
  508. if (!m_bInitialized)
  509. return false;
  510. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  511. return false;
  512. return m_pMainThread->UsingMlsd();
  513. }
  514. bool CFileZillaApi::UsingUtf8()
  515. {
  516. //Check if call allowed
  517. if (!m_bInitialized)
  518. return false;
  519. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  520. return false;
  521. return m_pMainThread->UsingUtf8();
  522. }
  523. std::string CFileZillaApi::GetTlsVersionStr()
  524. {
  525. //Check if call allowed
  526. if (!m_bInitialized)
  527. return std::string();
  528. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  529. return std::string();
  530. return m_pMainThread->GetTlsVersionStr();
  531. }
  532. std::string CFileZillaApi::GetCipherName()
  533. {
  534. //Check if call allowed
  535. if (!m_bInitialized)
  536. return std::string();
  537. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  538. return std::string();
  539. return m_pMainThread->GetCipherName();
  540. }
  541. #endif
  542. int CFileZillaApi::CustomCommand(CString CustomCommand)
  543. {
  544. //Check if call allowed
  545. if (!m_bInitialized)
  546. return FZ_REPLY_NOTINITIALIZED;
  547. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  548. return FZ_REPLY_NOTCONNECTED;
  549. if (IsBusy()==FZ_REPLY_BUSY)
  550. return FZ_REPLY_BUSY;
  551. t_server server;
  552. int res=GetCurrentServer(server);
  553. if (res!=FZ_REPLY_OK)
  554. return res;
  555. #ifndef MPEXT_NO_SFTP
  556. if (server.nServerType&FZ_SERVERTYPE_SUB_FTP_SFTP)
  557. return FZ_REPLY_NOTSUPPORTED;
  558. #endif
  559. if (CustomCommand==_MPT(""))
  560. return FZ_REPLY_INVALIDPARAM;
  561. t_command command;
  562. command.id=FZ_COMMAND_CUSTOMCOMMAND;
  563. command.param1=CustomCommand;
  564. m_pMainThread->Command(command);
  565. if (m_hOwnerWnd)
  566. return FZ_REPLY_WOULDBLOCK;
  567. else
  568. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  569. }
  570. int CFileZillaApi::Delete(CString FileName, const CServerPath &path /*=CServerPath()*/)
  571. {
  572. //Check if call allowed
  573. if (!m_bInitialized)
  574. return FZ_REPLY_NOTINITIALIZED;
  575. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  576. return FZ_REPLY_NOTCONNECTED;
  577. if (IsBusy()==FZ_REPLY_BUSY)
  578. return FZ_REPLY_BUSY;
  579. if (FileName=="")
  580. return FZ_REPLY_INVALIDPARAM;
  581. CServerPath path2=path;
  582. if (path2.IsEmpty())
  583. {
  584. m_pMainThread->GetCurrentPath(path2);
  585. if (path2.IsEmpty())
  586. return FZ_REPLY_INVALIDPARAM;
  587. }
  588. t_command command;
  589. command.id=FZ_COMMAND_DELETE;
  590. command.param1=FileName;
  591. command.path=path2;
  592. m_pMainThread->Command(command);
  593. if (m_hOwnerWnd)
  594. return FZ_REPLY_WOULDBLOCK;
  595. else
  596. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  597. }
  598. int CFileZillaApi::RemoveDir(CString DirName, const CServerPath &path /*=CServerPath()*/)
  599. {
  600. //Check if call allowed
  601. if (!m_bInitialized)
  602. return FZ_REPLY_NOTINITIALIZED;
  603. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  604. return FZ_REPLY_NOTCONNECTED;
  605. if (IsBusy()==FZ_REPLY_BUSY)
  606. return FZ_REPLY_BUSY;
  607. if (DirName==_MPT(""))
  608. return FZ_REPLY_INVALIDPARAM;
  609. CServerPath path2=path;
  610. if (path2.IsEmpty())
  611. {
  612. m_pMainThread->GetCurrentPath(path2);
  613. if (path2.IsEmpty())
  614. return FZ_REPLY_INVALIDPARAM;
  615. }
  616. t_command command;
  617. command.id=FZ_COMMAND_REMOVEDIR;
  618. command.param1=DirName;
  619. command.path=path2;
  620. m_pMainThread->Command(command);
  621. if (m_hOwnerWnd)
  622. return FZ_REPLY_WOULDBLOCK;
  623. else
  624. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  625. return FZ_REPLY_ERROR;
  626. }
  627. int CFileZillaApi::MakeDir(const CServerPath &path)
  628. {
  629. //Check if call allowed
  630. if (!m_bInitialized)
  631. return FZ_REPLY_NOTINITIALIZED;
  632. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  633. return FZ_REPLY_NOTCONNECTED;
  634. if (IsBusy()==FZ_REPLY_BUSY)
  635. return FZ_REPLY_BUSY;
  636. if (path.IsEmpty() || !path.HasParent())
  637. return FZ_REPLY_INVALIDPARAM;
  638. t_command command;
  639. command.id=FZ_COMMAND_MAKEDIR;
  640. command.path=path;
  641. m_pMainThread->Command(command);
  642. if (m_hOwnerWnd)
  643. return FZ_REPLY_WOULDBLOCK;
  644. else
  645. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  646. return FZ_REPLY_ERROR;
  647. }
  648. int CFileZillaApi::Rename(CString oldName, CString newName, const CServerPath &path /*=CServerPath()*/, const CServerPath &newPath /*=CServerPath()*/)
  649. {
  650. //Check if call allowed
  651. if (!m_bInitialized)
  652. return FZ_REPLY_NOTINITIALIZED;
  653. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  654. return FZ_REPLY_NOTCONNECTED;
  655. if (IsBusy()==FZ_REPLY_BUSY)
  656. return FZ_REPLY_BUSY;
  657. if (oldName==_MPT("") || newName==_MPT(""))
  658. return FZ_REPLY_INVALIDPARAM;
  659. CServerPath path2 = path;
  660. if (path2.IsEmpty())
  661. {
  662. m_pMainThread->GetCurrentPath(path2);
  663. if (path2.IsEmpty())
  664. return FZ_REPLY_INVALIDPARAM;
  665. }
  666. t_command command;
  667. command.id = FZ_COMMAND_RENAME;
  668. command.param1 = oldName;
  669. command.param2 = newName;
  670. command.path = path2;
  671. command.newPath = newPath;
  672. m_pMainThread->Command(command);
  673. if (m_hOwnerWnd)
  674. return FZ_REPLY_WOULDBLOCK;
  675. else
  676. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  677. return FZ_REPLY_ERROR;
  678. }
  679. int CFileZillaApi::SetAsyncRequestResult(int nAction, CAsyncRequestData *pData)
  680. {
  681. if (!this || !pData)
  682. return FZ_REPLY_CRITICALERROR | FZ_REPLY_INVALIDPARAM;
  683. if (IsBadWritePtr(pData, sizeof(CAsyncRequestData)))
  684. return FZ_REPLY_CRITICALERROR;
  685. if (!m_bInitialized)
  686. {
  687. delete pData;
  688. return FZ_REPLY_NOTINITIALIZED;
  689. }
  690. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  691. {
  692. delete pData;
  693. return FZ_REPLY_NOTCONNECTED;
  694. }
  695. switch(pData->nRequestType)
  696. {
  697. case FZ_ASYNCREQUEST_OVERWRITE:
  698. break;
  699. #ifndef MPEXT_NO_SSL
  700. case FZ_ASYNCREQUEST_VERIFYCERT:
  701. if (!((CVerifyCertRequestData *)pData)->pCertData)
  702. {
  703. delete pData;
  704. return FZ_REPLY_INVALIDPARAM;
  705. }
  706. break;
  707. #endif
  708. case FZ_ASYNCREQUEST_NEEDPASS:
  709. break;
  710. #ifndef MPEXT_NO_GSS
  711. case FZ_ASYNCREQUEST_GSS_AUTHFAILED:
  712. case FZ_ASYNCREQUEST_GSS_NEEDUSER:
  713. case FZ_ASYNCREQUEST_GSS_NEEDPASS:
  714. #ifdef MPEXT
  715. break;
  716. #endif
  717. #endif
  718. #ifndef MPEXT_NO_SFTP
  719. case FZ_ASYNCREQUEST_NEWHOSTKEY:
  720. case FZ_ASYNCREQUEST_CHANGEDHOSTKEY:
  721. break;
  722. #endif
  723. default:
  724. delete pData;
  725. return FZ_REPLY_INVALIDPARAM;
  726. }
  727. pData->nRequestResult = nAction;
  728. if (!m_pMainThread)
  729. {
  730. delete pData;
  731. return FZ_REPLY_NOTINITIALIZED;
  732. }
  733. m_pMainThread->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_ASYNCREQUESTREPLY, (LPARAM)pData);
  734. return FZ_REPLY_OK;
  735. }
  736. #ifndef MPEXT
  737. int CFileZillaApi::SetOption(int nOption, int value)
  738. {
  739. if (!m_bInitialized)
  740. return FZ_REPLY_NOTINITIALIZED;
  741. switch (nOption)
  742. {
  743. case FZAPI_OPTION_SHOWHIDDEN:
  744. m_pMainThread->SetOption(nOption, value);
  745. break;
  746. default:
  747. return FZ_REPLY_INVALIDPARAM;
  748. }
  749. return FZ_REPLY_OK;
  750. }
  751. int CFileZillaApi::GetOption(int nOption, int &value)
  752. {
  753. if (!m_bInitialized)
  754. return FZ_REPLY_NOTINITIALIZED;
  755. switch (nOption)
  756. {
  757. case FZAPI_OPTION_SHOWHIDDEN:
  758. value = m_pMainThread->GetOption(nOption);
  759. break;
  760. default:
  761. return FZ_REPLY_INVALIDPARAM;
  762. }
  763. return FZ_REPLY_OK;
  764. }
  765. #endif
  766. int CFileZillaApi::Chmod(int nValue, CString FileName, const CServerPath &path /*=CServerPath()*/ )
  767. {
  768. //Check if call allowed
  769. if (!m_bInitialized)
  770. return FZ_REPLY_NOTINITIALIZED;
  771. if (IsConnected()==FZ_REPLY_NOTCONNECTED)
  772. return FZ_REPLY_NOTCONNECTED;
  773. if (IsBusy()==FZ_REPLY_BUSY)
  774. return FZ_REPLY_BUSY;
  775. if (FileName==_MPT(""))
  776. return FZ_REPLY_INVALIDPARAM;
  777. t_command command;
  778. command.id=FZ_COMMAND_CHMOD;
  779. command.param1=FileName;
  780. command.param4=nValue;
  781. command.path=path;
  782. m_pMainThread->Command(command);
  783. if (m_hOwnerWnd)
  784. return FZ_REPLY_WOULDBLOCK;
  785. else
  786. return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR;
  787. }
  788. int CFileZillaApi::SetDebugLevel(int nDebugLevel)
  789. {
  790. //Check if call allowed
  791. if (!m_bInitialized)
  792. return FZ_REPLY_NOTINITIALIZED;
  793. if (!m_pMainThread->SetDebugLevel(nDebugLevel))
  794. return FZ_REPLY_ERROR;
  795. return FZ_REPLY_OK;
  796. }
  797. #ifndef MPEXT_NO_CACHE
  798. BOOL CFileZillaApi::DumpDirectoryCache(LPCTSTR pFileName)
  799. {
  800. CDirectoryCache cache;
  801. return cache.Dump(pFileName);
  802. }
  803. #endif
  804. //CAsyncRequestData derived classes
  805. CAsyncRequestData::CAsyncRequestData()
  806. {
  807. nRequestType = 0;
  808. nRequestID = 0;
  809. nRequestResult = 0;
  810. }
  811. CAsyncRequestData::~CAsyncRequestData()
  812. {
  813. }
  814. COverwriteRequestData::COverwriteRequestData()
  815. {
  816. size1 = 0;
  817. size2 = 0;
  818. nRequestType=FZ_ASYNCREQUEST_OVERWRITE;
  819. localtime=0;
  820. remotetime.hasdate = false;
  821. pTransferFile=0;
  822. }
  823. COverwriteRequestData::~COverwriteRequestData()
  824. {
  825. delete pTransferFile;
  826. delete localtime;
  827. }
  828. #ifndef MPEXT_NO_SSL
  829. CVerifyCertRequestData::CVerifyCertRequestData()
  830. {
  831. nRequestType=FZ_ASYNCREQUEST_VERIFYCERT;
  832. pCertData=0;
  833. }
  834. CVerifyCertRequestData::~CVerifyCertRequestData()
  835. {
  836. delete pCertData;
  837. }
  838. #endif
  839. CNeedPassRequestData::CNeedPassRequestData()
  840. {
  841. nRequestType=FZ_ASYNCREQUEST_NEEDPASS;
  842. nOldOpState=0;
  843. }
  844. CNeedPassRequestData::~CNeedPassRequestData()
  845. {
  846. }
  847. #ifndef MPEXT_NO_GSS
  848. CGssNeedPassRequestData::CGssNeedPassRequestData()
  849. {
  850. nRequestType=FZ_ASYNCREQUEST_GSS_NEEDPASS;
  851. }
  852. CGssNeedPassRequestData::~CGssNeedPassRequestData()
  853. {
  854. }
  855. CGssNeedUserRequestData::CGssNeedUserRequestData()
  856. {
  857. nRequestType = FZ_ASYNCREQUEST_GSS_NEEDUSER;
  858. }
  859. CGssNeedUserRequestData::~CGssNeedUserRequestData()
  860. {
  861. }
  862. #endif
  863. #ifndef MPEXT_NO_SFTP
  864. CNewHostKeyRequestData::CNewHostKeyRequestData()
  865. {
  866. nRequestType=FZ_ASYNCREQUEST_NEWHOSTKEY;
  867. }
  868. CNewHostKeyRequestData::~CNewHostKeyRequestData()
  869. {
  870. }
  871. CChangedHostKeyRequestData::CChangedHostKeyRequestData()
  872. {
  873. nRequestType=FZ_ASYNCREQUEST_CHANGEDHOSTKEY;
  874. }
  875. CChangedHostKeyRequestData::~CChangedHostKeyRequestData()
  876. {
  877. }
  878. #endif
  879. BOOL CFileZillaApi::IsValid() const
  880. {
  881. if (!this)
  882. return FALSE;
  883. if (IsBadWritePtr((VOID *)this, sizeof(CFileZillaApi)) )
  884. return FALSE;
  885. if (IsBadWritePtr((VOID *)&m_bInitialized, sizeof(BOOL)) ||
  886. IsBadWritePtr((VOID *)&m_hOwnerWnd, sizeof(HWND)) ||
  887. IsBadWritePtr((VOID *)&m_nInternalMessageID, sizeof(unsigned int)) ||
  888. IsBadWritePtr((VOID *)&m_nReplyMessageID, sizeof(unsigned int)) ||
  889. IsBadWritePtr(m_pMainThread, sizeof(CMainThread)) )
  890. return FALSE;
  891. if (!m_pMainThread->IsValid())
  892. return FALSE;
  893. return TRUE;
  894. }