stdafx.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. //---------------------------------------------------------------------------
  2. #ifndef StdAfxH
  3. #define StdAfxH
  4. //---------------------------------------------------------------------------
  5. #define _int64 __int64
  6. //---------------------------------------------------------------------------
  7. #define MPEXT
  8. #define MPEXT_NO_ZLIB
  9. #define MPEXT_NO_GSS
  10. #define MPEXT_NO_SFTP
  11. #define MPEXT_NO_IDENT
  12. #define MPEXT_NO_CACHE
  13. #define MPEXT_NO_SPEED_LIM_RULES
  14. #define MPEXT_NO_SSLDLL
  15. #define _AFX_NOFORCE_LIBS
  16. #define _MPT(T) _T(T)
  17. #define _MPAT(T) T
  18. //---------------------------------------------------------------------------
  19. #define GetOption(OPTION) GetInstanceOption(this->m_pApiLogParent, OPTION)
  20. #define GetOptionVal(OPTION) GetInstanceOptionVal(this->m_pApiLogParent, OPTION)
  21. //---------------------------------------------------------------------------
  22. #define LENOF(x) ( (sizeof((x))) / (sizeof(*(x))))
  23. //---------------------------------------------------------------------------
  24. #include <afx.h>
  25. #include "wtypes.h"
  26. #include <afxmt.h>
  27. //STL includes
  28. #include <list>
  29. #include <map>
  30. #include <vector>
  31. #include <deque>
  32. #include <set>
  33. #include <algorithm>
  34. //---------------------------------------------------------------------------
  35. class CFileFix;
  36. #define CFile CFileFix
  37. //---------------------------------------------------------------------------
  38. #include "MFC64bitFix.h"
  39. #include <ApiLog.h>
  40. #include <FileZillaApi.h>
  41. #include <FileZillaOpt.h>
  42. #include <Options.h>
  43. #include <Crypt.h>
  44. #include <TextsFileZilla.h>
  45. #include <structures.h>
  46. //---------------------------------------------------------------------------
  47. #include <oleauto.h>
  48. #include <afxdisp.h>
  49. #include <afxconv.h>
  50. //---------------------------------------------------------------------------
  51. #define _strlwr strlwr
  52. #define USEDPARAM(p) ((p) == (p))
  53. //---------------------------------------------------------------------------
  54. #ifdef _DEBUG
  55. #ifndef ASSERT
  56. #error ASSERT should be defined here by afx.h
  57. #endif
  58. #undef ASSERT
  59. // Copy of afx.h ASSERT with TRACE added.
  60. // Better would be to hook afxAssertFailedLine
  61. #define ASSERT(f) \
  62. do \
  63. { \
  64. if (!(f)) \
  65. { \
  66. if (AfxAssertFailedLine(THIS_FILE, __LINE__)) \
  67. { \
  68. AfxDebugBreak(); \
  69. } \
  70. } \
  71. } while (0)
  72. #endif
  73. //---------------------------------------------------------------------------
  74. const int FILEEXISTS_ASK = -1;
  75. const int FILEEXISTS_OVERWRITE = 0;
  76. const int FILEEXISTS_OVERWRITEIFNEWER = 1;
  77. const int FILEEXISTS_RESUME = 2;
  78. const int FILEEXISTS_RENAME = 3;
  79. const int FILEEXISTS_SKIP = 4;
  80. const int FILEEXISTS_RESUME_ASKONFAIL = 5; // Used by queue for automatic resuming. If APPE failes, ask what to do instead.
  81. const int FILEEXISTS_COMPLETE = 6;
  82. //---------------------------------------------------------------------------
  83. class t_ffam_statusmessage
  84. {
  85. public:
  86. CString status;
  87. int type;
  88. BOOL post;
  89. };
  90. //---------------------------------------------------------------------------
  91. typedef struct
  92. {
  93. __int64 bytes;
  94. #ifdef MPEXT
  95. __int64 transfersize;
  96. #endif
  97. int percent;
  98. int timeelapsed;
  99. int timeleft;
  100. int transferrate;
  101. BOOL bFileTransfer;
  102. } t_ffam_transferstatus;
  103. //---------------------------------------------------------------------------
  104. #undef CFile
  105. //---------------------------------------------------------------------------
  106. class CFileFix : public CFile
  107. {
  108. public:
  109. // MFC CFile::Read does not include file name into error message
  110. UINT Read(void * lpBuf, UINT nCount)
  111. {
  112. ASSERT_VALID(this);
  113. ASSERT(m_hFile != (UINT)hFileNull);
  114. if (nCount == 0)
  115. {
  116. return 0; // avoid Win32 "null-read"
  117. }
  118. ASSERT(lpBuf != NULL);
  119. ASSERT(AfxIsValidAddress(lpBuf, nCount));
  120. DWORD dwRead;
  121. if (!::ReadFile((HANDLE)m_hFile, lpBuf, nCount, &dwRead, NULL))
  122. {
  123. // The only change from MFC CFile::Read is m_strFileName
  124. CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName);
  125. }
  126. return (UINT)dwRead;
  127. }
  128. // MFC allocates CObject (ancestor of CFile) with new, but deallocates with free,
  129. // what codeguard dislikes, this is fix, not sure if it is necessary for
  130. // release version, but probably causes no harm
  131. void PASCAL operator delete(void* p)
  132. {
  133. delete p;
  134. }
  135. };
  136. //---------------------------------------------------------------------------
  137. #define CFile CFileFix
  138. //---------------------------------------------------------------------------
  139. struct CStringDataA
  140. {
  141. long nRefs; // reference count
  142. int nDataLength; // length of data (including terminator)
  143. int nAllocLength; // length of allocation
  144. //char data[nAllocLength];
  145. CHAR* data() // CHAR* to managed data
  146. {
  147. return (CHAR*)(this+1);
  148. }
  149. };
  150. //---------------------------------------------------------------------------
  151. extern LPCSTR _afxPchNilA;
  152. extern CStringDataA* _afxDataNilA;
  153. #define afxEmptyStringA ((CStringA&)*(CStringA*)&_afxPchNilA)
  154. //---------------------------------------------------------------------------
  155. class CStringA
  156. {
  157. public:
  158. CStringA()
  159. {
  160. m_pchData = afxEmptyStringA.m_pchData;
  161. }
  162. CStringA(const CStringA& stringSrc)
  163. {
  164. ASSERT(stringSrc.GetData()->nRefs != 0);
  165. if (stringSrc.GetData()->nRefs >= 0)
  166. {
  167. ASSERT(stringSrc.GetData() != _afxDataNilA);
  168. m_pchData = stringSrc.m_pchData;
  169. InterlockedIncrement(&GetData()->nRefs);
  170. }
  171. else
  172. {
  173. Init();
  174. *this = stringSrc.m_pchData;
  175. }
  176. }
  177. CStringA(LPCSTR lpsz)
  178. {
  179. Init();
  180. if (lpsz != NULL && HIWORD(lpsz) == NULL)
  181. {
  182. ASSERT(false);
  183. }
  184. else
  185. {
  186. int nLen = SafeStrlen(lpsz);
  187. if (nLen != 0)
  188. {
  189. AllocBuffer(nLen);
  190. memcpy(m_pchData, lpsz, nLen*sizeof(char));
  191. }
  192. }
  193. }
  194. ~CStringA()
  195. {
  196. if (GetData() != _afxDataNilA)
  197. {
  198. if (InterlockedDecrement(&GetData()->nRefs) <= 0)
  199. {
  200. FreeData(GetData());
  201. }
  202. }
  203. }
  204. int GetLength() const
  205. {
  206. return GetData()->nDataLength;
  207. }
  208. char operator[](int nIndex) const
  209. {
  210. // same as GetAt
  211. ASSERT(nIndex >= 0);
  212. ASSERT(nIndex < GetData()->nDataLength);
  213. return m_pchData[nIndex];
  214. }
  215. // ref-counted copy from another CString
  216. CStringA& operator=(const CStringA& stringSrc)
  217. {
  218. if (m_pchData != stringSrc.m_pchData)
  219. {
  220. if ((GetData()->nRefs < 0 && GetData() != _afxDataNilA) ||
  221. stringSrc.GetData()->nRefs < 0)
  222. {
  223. // actual copy necessary since one of the strings is locked
  224. AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
  225. }
  226. else
  227. {
  228. // can just copy references around
  229. Release();
  230. ASSERT(stringSrc.GetData() != _afxDataNilA);
  231. m_pchData = stringSrc.m_pchData;
  232. InterlockedIncrement(&GetData()->nRefs);
  233. }
  234. }
  235. return *this;
  236. }
  237. const CStringA& operator=(LPCSTR lpsz)
  238. {
  239. ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
  240. AssignCopy(SafeStrlen(lpsz), lpsz);
  241. return *this;
  242. }
  243. const CStringA& operator+=(char ch)
  244. {
  245. ConcatInPlace(1, &ch);
  246. return *this;
  247. }
  248. friend CStringA AFXAPI operator+(const CStringA& string, char ch);
  249. operator LPCSTR() const
  250. {
  251. return m_pchData;
  252. }
  253. int Compare(LPCSTR lpsz) const
  254. {
  255. ASSERT(AfxIsValidString(lpsz));
  256. return strcmp(m_pchData, lpsz);
  257. }
  258. CStringA Mid(int nFirst, int nCount) const
  259. {
  260. // out-of-bounds requests return sensible things
  261. if (nFirst < 0)
  262. {
  263. nFirst = 0;
  264. }
  265. if (nCount < 0)
  266. {
  267. nCount = 0;
  268. }
  269. if (nFirst + nCount > GetData()->nDataLength)
  270. {
  271. nCount = GetData()->nDataLength - nFirst;
  272. }
  273. if (nFirst > GetData()->nDataLength)
  274. {
  275. nCount = 0;
  276. }
  277. ASSERT(nFirst >= 0);
  278. ASSERT(nFirst + nCount <= GetData()->nDataLength);
  279. // optimize case of returning entire string
  280. if (nFirst == 0 && nFirst + nCount == GetData()->nDataLength)
  281. {
  282. return *this;
  283. }
  284. CStringA dest;
  285. AllocCopy(dest, nCount, nFirst, 0);
  286. return dest;
  287. }
  288. CStringA Left(int nCount) const
  289. {
  290. if (nCount < 0)
  291. {
  292. nCount = 0;
  293. }
  294. if (nCount >= GetData()->nDataLength)
  295. {
  296. return *this;
  297. }
  298. CStringA dest;
  299. AllocCopy(dest, nCount, 0, 0);
  300. return dest;
  301. }
  302. int Find(char ch) const
  303. {
  304. return Find(ch, 0);
  305. }
  306. int Find(char ch, int nStart) const
  307. {
  308. int nLength = GetData()->nDataLength;
  309. if (nStart >= nLength)
  310. {
  311. return -1;
  312. }
  313. // find first single character
  314. LPSTR lpsz = strchr(m_pchData + nStart, (unsigned char)ch);
  315. // return -1 if not found and index otherwise
  316. return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
  317. }
  318. // find a sub-string (like strstr)
  319. int Find(LPCSTR lpszSub) const
  320. {
  321. return Find(lpszSub, 0);
  322. }
  323. int Find(LPCSTR lpszSub, int nStart) const
  324. {
  325. ASSERT(AfxIsValidString(lpszSub));
  326. int nLength = GetData()->nDataLength;
  327. if (nStart > nLength)
  328. {
  329. return -1;
  330. }
  331. // find first matching substring
  332. LPSTR lpsz = strstr(m_pchData + nStart, lpszSub);
  333. // return -1 for not found, distance from beginning otherwise
  334. return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
  335. }
  336. void MakeUpper()
  337. {
  338. CopyBeforeWrite();
  339. strupr(m_pchData);
  340. }
  341. protected:
  342. LPSTR m_pchData; // pointer to ref counted string data
  343. CStringDataA* GetData() const
  344. {
  345. ASSERT(m_pchData != NULL); return ((CStringDataA*)m_pchData)-1;
  346. }
  347. void Init()
  348. {
  349. m_pchData = afxEmptyStringA.m_pchData;
  350. }
  351. void AllocCopy(CStringA& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const
  352. {
  353. // will clone the data attached to this string
  354. // allocating 'nExtraLen' characters
  355. // Places results in uninitialized string 'dest'
  356. // Will copy the part or all of original data to start of new string
  357. int nNewLen = nCopyLen + nExtraLen;
  358. if (nNewLen == 0)
  359. {
  360. dest.Init();
  361. }
  362. else
  363. {
  364. dest.AllocBuffer(nNewLen);
  365. memcpy(dest.m_pchData, m_pchData+nCopyIndex, nCopyLen*sizeof(char));
  366. }
  367. }
  368. void AllocBuffer(int nLen)
  369. // always allocate one extra character for '\0' termination
  370. // assumes [optimistically] that data length will equal allocation length
  371. {
  372. ASSERT(nLen >= 0);
  373. ASSERT(nLen <= INT_MAX-1); // max size (enough room for 1 extra)
  374. if (nLen == 0)
  375. {
  376. Init();
  377. }
  378. else
  379. {
  380. CStringDataA* pData;
  381. {
  382. pData = (CStringDataA*)
  383. new BYTE[sizeof(CStringDataA) + (nLen+1)*sizeof(char)];
  384. pData->nAllocLength = nLen;
  385. }
  386. pData->nRefs = 1;
  387. pData->data()[nLen] = '\0';
  388. pData->nDataLength = nLen;
  389. m_pchData = pData->data();
  390. }
  391. }
  392. void AssignCopy(int nSrcLen, LPCSTR lpszSrcData)
  393. {
  394. AllocBeforeWrite(nSrcLen);
  395. memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(char));
  396. GetData()->nDataLength = nSrcLen;
  397. m_pchData[nSrcLen] = '\0';
  398. }
  399. void FASTCALL FreeData(CStringDataA* pData)
  400. {
  401. delete[] (BYTE*)pData;
  402. }
  403. void PASCAL Release(CStringDataA* pData)
  404. {
  405. if (pData != _afxDataNilA)
  406. {
  407. ASSERT(pData->nRefs != 0);
  408. if (InterlockedDecrement(&pData->nRefs) <= 0)
  409. {
  410. FreeData(pData);
  411. }
  412. }
  413. }
  414. void Release()
  415. {
  416. if (GetData() != _afxDataNilA)
  417. {
  418. ASSERT(GetData()->nRefs != 0);
  419. if (InterlockedDecrement(&GetData()->nRefs) <= 0)
  420. {
  421. FreeData(GetData());
  422. }
  423. Init();
  424. }
  425. }
  426. void ConcatCopy(int nSrc1Len, LPCSTR lpszSrc1Data, int nSrc2Len, LPCSTR lpszSrc2Data)
  427. {
  428. // -- master concatenation routine
  429. // Concatenate two sources
  430. // -- assume that 'this' is a new CString object
  431. int nNewLen = nSrc1Len + nSrc2Len;
  432. if (nNewLen != 0)
  433. {
  434. AllocBuffer(nNewLen);
  435. memcpy(m_pchData, lpszSrc1Data, nSrc1Len*sizeof(char));
  436. memcpy(m_pchData+nSrc1Len, lpszSrc2Data, nSrc2Len*sizeof(char));
  437. }
  438. }
  439. void ConcatInPlace(int nSrcLen, LPCSTR lpszSrcData)
  440. {
  441. // -- the main routine for += operators
  442. // concatenating an empty string is a no-op!
  443. if (nSrcLen == 0)
  444. {
  445. return;
  446. }
  447. // if the buffer is too small, or we have a width mis-match, just
  448. // allocate a new buffer (slow but sure)
  449. if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength)
  450. {
  451. // we have to grow the buffer, use the ConcatCopy routine
  452. CStringDataA* pOldData = GetData();
  453. ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData);
  454. ASSERT(pOldData != NULL);
  455. CStringA::Release(pOldData);
  456. }
  457. else
  458. {
  459. // fast concatenation when buffer big enough
  460. memcpy(m_pchData+GetData()->nDataLength, lpszSrcData, nSrcLen*sizeof(char));
  461. GetData()->nDataLength += nSrcLen;
  462. ASSERT(GetData()->nDataLength <= GetData()->nAllocLength);
  463. m_pchData[GetData()->nDataLength] = '\0';
  464. }
  465. }
  466. void CopyBeforeWrite()
  467. {
  468. if (GetData()->nRefs > 1)
  469. {
  470. CStringDataA* pData = GetData();
  471. Release();
  472. AllocBuffer(pData->nDataLength);
  473. memcpy(m_pchData, pData->data(), (pData->nDataLength+1)*sizeof(char));
  474. }
  475. ASSERT(GetData()->nRefs <= 1);
  476. }
  477. void AllocBeforeWrite(int nLen)
  478. {
  479. if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength)
  480. {
  481. Release();
  482. AllocBuffer(nLen);
  483. }
  484. ASSERT(GetData()->nRefs <= 1);
  485. }
  486. static int PASCAL SafeStrlen(LPCSTR lpsz)
  487. {
  488. return (lpsz == NULL) ? 0 : strlen(lpsz);
  489. }
  490. };
  491. //---------------------------------------------------------------------------
  492. inline bool AFXAPI operator==(const CStringA& s1, LPCSTR s2)
  493. {
  494. return s1.Compare(s2) == 0;
  495. }
  496. //---------------------------------------------------------------------------
  497. inline bool AFXAPI operator!=(const CStringA& s1, LPCSTR s2)
  498. {
  499. return s1.Compare(s2) != 0;
  500. }
  501. //---------------------------------------------------------------------------
  502. inline CStringA AFXAPI operator+(const CStringA& string1, char ch)
  503. {
  504. CStringA s;
  505. s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, 1, &ch);
  506. return s;
  507. }
  508. //---------------------------------------------------------------------------
  509. #endif