stdafx.h 14 KB

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