stdafx.h 14 KB

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