Misc.cpp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441
  1. #include "stdafx.h"
  2. #include "CP_Main.h"
  3. #include "Misc.h"
  4. #include "OptionsSheet.h"
  5. #include "shared/TextConvert.h"
  6. #include "AlphaBlend.h"
  7. #include "Tlhelp32.h"
  8. #include <Wininet.h>
  9. #include "sqlite\utext.h"
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include "Path.h"
  13. CString GetIPAddress()
  14. {
  15. WORD wVersionRequested;
  16. WSADATA wsaData;
  17. char name[255];
  18. CString IP;
  19. PHOSTENT hostinfo;
  20. wVersionRequested = MAKEWORD(2,0);
  21. if (WSAStartup(wVersionRequested, &wsaData)==0)
  22. {
  23. if(gethostname(name, sizeof(name))==0)
  24. {
  25. if((hostinfo=gethostbyname(name)) != NULL)
  26. {
  27. IP = inet_ntoa(*(struct in_addr*)* hostinfo->h_addr_list);
  28. }
  29. }
  30. WSACleanup();
  31. }
  32. IP.MakeUpper();
  33. return IP;
  34. }
  35. CString GetComputerName()
  36. {
  37. TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH+1] = _T("");
  38. DWORD Size=MAX_COMPUTERNAME_LENGTH+1;
  39. GetComputerName(ComputerName, &Size);
  40. CString cs(ComputerName);
  41. cs.MakeUpper();
  42. return cs;
  43. }
  44. void AppendToFile(const TCHAR* fn, const TCHAR* msg)
  45. {
  46. #ifdef _UNICODE
  47. FILE *file = _wfopen(fn, _T("a"));
  48. #else
  49. FILE *file = fopen(fn, _T("a"));
  50. #endif
  51. ASSERT( file );
  52. if(file != NULL)
  53. {
  54. #ifdef _UNICODE
  55. fwprintf(file, _T("%s"), msg);
  56. #else
  57. fprintf(file, _T("%s"),msg);
  58. #endif
  59. fclose(file);
  60. }
  61. }
  62. void log(const TCHAR* msg, bool bFromSendRecieve, CString csFile, long lLine)
  63. {
  64. ASSERT(AfxIsValidString(msg));
  65. SYSTEMTIME st;
  66. GetLocalTime(&st);
  67. CString csText;
  68. csText.Format(_T("[%d/%d/%d %02d:%02d:%02d.%03d - "), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
  69. CString csFileLine;
  70. csFile = GetFileName(csFile);
  71. csFileLine.Format(_T("%s %d] "), csFile, lLine);
  72. csText += csFileLine;
  73. csText += msg;
  74. csText += "\n";
  75. #ifndef _DEBUG
  76. if(CGetSetOptions::m_bOutputDebugString)
  77. #endif
  78. {
  79. OutputDebugString(csText);
  80. }
  81. #ifndef _DEBUG
  82. if(!bFromSendRecieve)
  83. {
  84. if(!g_Opt.m_bEnableDebugLogging)
  85. return;
  86. }
  87. #endif
  88. CString csExeFile = CGetSetOptions::GetPath(PATH_LOG_FILE);
  89. csExeFile += "Ditto.log";
  90. AppendToFile(csExeFile, csText);
  91. }
  92. void logsendrecieveinfo(CString cs, CString csFile, long lLine)
  93. {
  94. if(g_Opt.m_bLogSendReceiveErrors)
  95. log(cs, true, csFile, lLine);
  96. }
  97. CString GetErrorString( int err )
  98. {
  99. CString str;
  100. LPVOID lpMsgBuf;
  101. ::FormatMessage(
  102. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  103. NULL,
  104. err,
  105. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  106. (LPTSTR) &lpMsgBuf,
  107. 0,
  108. NULL
  109. );
  110. str = (LPCTSTR) lpMsgBuf;
  111. // Display the string.
  112. // ::MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
  113. ::LocalFree( lpMsgBuf );
  114. return str;
  115. }
  116. int g_funnyGetTickCountAdjustment = -1;
  117. double IdleSeconds()
  118. {
  119. LASTINPUTINFO info;
  120. info.cbSize = sizeof(info);
  121. GetLastInputInfo(&info);
  122. DWORD currentTick = GetTickCount();
  123. if(g_funnyGetTickCountAdjustment == -1)
  124. {
  125. if(currentTick < info.dwTime)
  126. {
  127. g_funnyGetTickCountAdjustment = 1;
  128. }
  129. else
  130. {
  131. g_funnyGetTickCountAdjustment = 0;
  132. }
  133. }
  134. if(g_funnyGetTickCountAdjustment == 1 || g_funnyGetTickCountAdjustment == 2)
  135. {
  136. //Output message the first time
  137. if(g_funnyGetTickCountAdjustment == 1)
  138. {
  139. Log(StrF(_T("Adjusting time of get tickcount by: %d, on startup we found GetTickCount to be less than last input"), CGetSetOptions::GetFunnyTickCountAdjustment()));
  140. g_funnyGetTickCountAdjustment = 2;
  141. }
  142. currentTick += CGetSetOptions::GetFunnyTickCountAdjustment();
  143. }
  144. double idleSeconds = (currentTick - info.dwTime)/1000.0;
  145. return idleSeconds;
  146. }
  147. CString StrF(const TCHAR * pszFormat, ...)
  148. {
  149. ASSERT( AfxIsValidString( pszFormat ) );
  150. CString str;
  151. va_list argList;
  152. va_start( argList, pszFormat );
  153. str.FormatV( pszFormat, argList );
  154. va_end( argList );
  155. return str;
  156. }
  157. BYTE GetEscapeChar( BYTE ch )
  158. {
  159. switch(ch)
  160. {
  161. case '\'': return '\''; // Single quotation mark (') = 39 or 0x27
  162. case '\"': return '\"'; // Double quotation mark (") = 34 or 0x22
  163. case '?': return '\?'; // Question mark (?) = 63 or 0x3f
  164. case '\\': return '\\'; // Backslash (\) = 92 or 0x5c
  165. case 'a': return '\a'; // Alert (BEL) = 7
  166. case 'b': return '\b'; // Backspace (BS) = 8
  167. case 'f': return '\f'; // Formfeed (FF) = 12 or 0x0c
  168. case 'n': return '\n'; // Newline (NL or LF) = 10 or 0x0a
  169. case 'r': return '\r'; // Carriage Return (CR) = 13 or 0x0d
  170. case 't': return '\t'; // Horizontal tab (HT) = 9
  171. case 'v': return '\v'; // Vertical tab (VT) = 11 or 0x0b
  172. case '0': return '\0'; // Null character (NUL) = 0
  173. }
  174. return 0; // invalid
  175. }
  176. CString RemoveEscapes( const TCHAR* str )
  177. {
  178. ASSERT( str );
  179. CString ret;
  180. TCHAR* pSrc = (TCHAR*) str;
  181. TCHAR* pDest = ret.GetBuffer((int)STRLEN(pSrc));
  182. TCHAR* pStart = pDest;
  183. while( *pSrc != '\0' )
  184. {
  185. if( *pSrc == '\\' )
  186. {
  187. pSrc++;
  188. *pDest = GetEscapeChar((BYTE)pSrc );
  189. }
  190. else
  191. *pDest = *pSrc;
  192. pSrc++;
  193. pDest++;
  194. }
  195. ret.ReleaseBuffer((int)(pDest - pStart));
  196. return ret;
  197. }
  198. CString GetWndText( HWND hWnd )
  199. {
  200. CString text;
  201. if( !IsWindow(hWnd) )
  202. return "! NOT A VALID WINDOW !";
  203. CWnd* pWnd = CWnd::FromHandle(hWnd);
  204. pWnd->GetWindowText(text);
  205. return text;
  206. }
  207. bool IsAppWnd( HWND hWnd )
  208. {
  209. DWORD dwMyPID = ::GetCurrentProcessId();
  210. DWORD dwTestPID;
  211. ::GetWindowThreadProcessId( hWnd, &dwTestPID );
  212. return dwMyPID == dwTestPID;
  213. }
  214. /*----------------------------------------------------------------------------*\
  215. Global Memory Helper Functions
  216. \*----------------------------------------------------------------------------*/
  217. // make sure the given HGLOBAL is valid.
  218. BOOL IsValid(HGLOBAL hGlobal)
  219. {
  220. void* pvData = ::GlobalLock(hGlobal);
  221. ::GlobalUnlock(hGlobal);
  222. return (pvData != NULL);
  223. }
  224. // asserts if hDest isn't big enough
  225. void CopyToGlobalHP(HGLOBAL hDest, LPVOID pBuf, SIZE_T ulBufLen)
  226. {
  227. ASSERT(hDest && pBuf && ulBufLen);
  228. LPVOID pvData = GlobalLock(hDest);
  229. ASSERT(pvData);
  230. SIZE_T size = GlobalSize(hDest);
  231. ASSERT(size >= ulBufLen); // assert if hDest isn't big enough
  232. memcpy(pvData, pBuf, ulBufLen);
  233. GlobalUnlock(hDest);
  234. }
  235. void CopyToGlobalHH(HGLOBAL hDest, HGLOBAL hSource, SIZE_T ulBufLen)
  236. {
  237. ASSERT(hDest && hSource && ulBufLen);
  238. LPVOID pvData = GlobalLock(hSource);
  239. ASSERT(pvData );
  240. SIZE_T size = GlobalSize(hSource);
  241. ASSERT(size >= ulBufLen); // assert if hSource isn't big enough
  242. CopyToGlobalHP(hDest, pvData, ulBufLen);
  243. GlobalUnlock(hSource);
  244. }
  245. HGLOBAL NewGlobalP(LPVOID pBuf, SIZE_T nLen)
  246. {
  247. ASSERT(pBuf && nLen);
  248. HGLOBAL hDest = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, nLen);
  249. ASSERT(hDest );
  250. CopyToGlobalHP(hDest, pBuf, nLen);
  251. return hDest;
  252. }
  253. HGLOBAL NewGlobal(SIZE_T nLen)
  254. {
  255. ASSERT(nLen);
  256. HGLOBAL hDest = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, nLen);
  257. return hDest;
  258. }
  259. HGLOBAL NewGlobalH(HGLOBAL hSource, SIZE_T nLen)
  260. {
  261. ASSERT(hSource && nLen);
  262. LPVOID pvData = GlobalLock(hSource);
  263. HGLOBAL hDest = NewGlobalP(pvData, nLen);
  264. GlobalUnlock(hSource);
  265. return hDest;
  266. }
  267. int CompareGlobalHP(HGLOBAL hLeft, LPVOID pBuf, SIZE_T ulBufLen)
  268. {
  269. ASSERT(hLeft && pBuf && ulBufLen);
  270. LPVOID pvData = GlobalLock(hLeft);
  271. ASSERT(pvData);
  272. ASSERT(ulBufLen <= GlobalSize(hLeft));
  273. int result = memcmp(pvData, pBuf, ulBufLen);
  274. GlobalUnlock(hLeft);
  275. return result;
  276. }
  277. int CompareGlobalHH( HGLOBAL hLeft, HGLOBAL hRight, SIZE_T ulBufLen)
  278. {
  279. ASSERT(hLeft && hRight && ulBufLen);
  280. ASSERT(ulBufLen <= GlobalSize(hRight));
  281. LPVOID pvData = GlobalLock(hRight);
  282. ASSERT(pvData);
  283. int result = CompareGlobalHP(hLeft, pvData, ulBufLen);
  284. GlobalUnlock(hLeft);
  285. return result;
  286. }
  287. //Do not change these these are stored in the database
  288. CLIPFORMAT GetFormatID(LPCTSTR cbName)
  289. {
  290. if(STRCMP(cbName, _T("CF_TEXT")) == 0)
  291. return CF_TEXT;
  292. else if(STRCMP(cbName, _T("CF_METAFILEPICT")) == 0)
  293. return CF_METAFILEPICT;
  294. else if(STRCMP(cbName, _T("CF_SYLK")) == 0)
  295. return CF_SYLK;
  296. else if(STRCMP(cbName, _T("CF_DIF")) == 0)
  297. return CF_DIF;
  298. else if(STRCMP(cbName, _T("CF_TIFF")) == 0)
  299. return CF_TIFF;
  300. else if(STRCMP(cbName, _T("CF_OEMTEXT")) == 0)
  301. return CF_OEMTEXT;
  302. else if(STRCMP(cbName, _T("CF_DIB")) == 0)
  303. return CF_DIB;
  304. else if(STRCMP(cbName, _T("CF_PALETTE")) == 0)
  305. return CF_PALETTE;
  306. else if(STRCMP(cbName, _T("CF_PENDATA")) == 0)
  307. return CF_PENDATA;
  308. else if(STRCMP(cbName, _T("CF_RIFF")) == 0)
  309. return CF_RIFF;
  310. else if(STRCMP(cbName, _T("CF_WAVE")) == 0)
  311. return CF_WAVE;
  312. else if(STRCMP(cbName, _T("CF_UNICODETEXT")) == 0)
  313. return CF_UNICODETEXT;
  314. else if(STRCMP(cbName, _T("CF_ENHMETAFILE")) == 0)
  315. return CF_ENHMETAFILE;
  316. else if(STRCMP(cbName, _T("CF_HDROP")) == 0)
  317. return CF_HDROP;
  318. else if(STRCMP(cbName, _T("CF_LOCALE")) == 0)
  319. return CF_LOCALE;
  320. else if(STRCMP(cbName, _T("CF_OWNERDISPLAY")) == 0)
  321. return CF_OWNERDISPLAY;
  322. else if(STRCMP(cbName, _T("CF_DSPTEXT")) == 0)
  323. return CF_DSPTEXT;
  324. else if(STRCMP(cbName, _T("CF_DSPBITMAP")) == 0)
  325. return CF_DSPBITMAP;
  326. else if(STRCMP(cbName, _T("CF_DSPMETAFILEPICT")) == 0)
  327. return CF_DSPMETAFILEPICT;
  328. else if(STRCMP(cbName, _T("CF_DSPENHMETAFILE")) == 0)
  329. return CF_DSPENHMETAFILE;
  330. return ::RegisterClipboardFormat(cbName);
  331. }
  332. //Do not change these these are stored in the database
  333. CString GetFormatName(CLIPFORMAT cbType)
  334. {
  335. switch(cbType)
  336. {
  337. case CF_TEXT:
  338. return _T("CF_TEXT");
  339. case CF_BITMAP:
  340. return _T("CF_BITMAP");
  341. case CF_METAFILEPICT:
  342. return _T("CF_METAFILEPICT");
  343. case CF_SYLK:
  344. return _T("CF_SYLK");
  345. case CF_DIF:
  346. return _T("CF_DIF");
  347. case CF_TIFF:
  348. return _T("CF_TIFF");
  349. case CF_OEMTEXT:
  350. return _T("CF_OEMTEXT");
  351. case CF_DIB:
  352. return _T("CF_DIB");
  353. case CF_PALETTE:
  354. return _T("CF_PALETTE");
  355. case CF_PENDATA:
  356. return _T("CF_PENDATA");
  357. case CF_RIFF:
  358. return _T("CF_RIFF");
  359. case CF_WAVE:
  360. return _T("CF_WAVE");
  361. case CF_UNICODETEXT:
  362. return _T("CF_UNICODETEXT");
  363. case CF_ENHMETAFILE:
  364. return _T("CF_ENHMETAFILE");
  365. case CF_HDROP:
  366. return _T("CF_HDROP");
  367. case CF_LOCALE:
  368. return _T("CF_LOCALE");
  369. case CF_OWNERDISPLAY:
  370. return _T("CF_OWNERDISPLAY");
  371. case CF_DSPTEXT:
  372. return _T("CF_DSPTEXT");
  373. case CF_DSPBITMAP:
  374. return _T("CF_DSPBITMAP");
  375. case CF_DSPMETAFILEPICT:
  376. return _T("CF_DSPMETAFILEPICT");
  377. case CF_DSPENHMETAFILE:
  378. return _T("CF_DSPENHMETAFILE");
  379. default:
  380. //Not a default type get the name from the clipboard
  381. if (cbType != 0)
  382. {
  383. TCHAR szFormat[256];
  384. GetClipboardFormatName(cbType, szFormat, 256);
  385. return szFormat;
  386. }
  387. break;
  388. }
  389. return "ERROR";
  390. }
  391. CString GetFilePath(CString csFileName)
  392. {
  393. long lSlash = csFileName.ReverseFind('\\');
  394. if(lSlash > -1)
  395. {
  396. csFileName = csFileName.Left(lSlash + 1);
  397. }
  398. return csFileName;
  399. }
  400. CString GetFileName(CString csFileName)
  401. {
  402. long lSlash = csFileName.ReverseFind('\\');
  403. if(lSlash > -1)
  404. {
  405. csFileName = csFileName.Right(csFileName.GetLength() - lSlash - 1);
  406. }
  407. return csFileName;
  408. }
  409. /****************************************************************************************************
  410. BOOL CALLBACK MyMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
  411. ***************************************************************************************************/
  412. typedef struct
  413. {
  414. long lFlags; // Flags
  415. LPRECT pVirtualRect; // Ptr to rect that receives the results, or the src of the monitor search method
  416. int iMonitor; // Ndx to the mointor to look at, -1 for all, -or- result of the monitor search method
  417. int nMonitorCount; // Total number of monitors found, -1 for monitor search method
  418. } MONITOR_ENUM_PARAM;
  419. #define MONITOR_SEARCH_METOHD 0x00000001
  420. BOOL CALLBACK MyMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
  421. {
  422. // Typecast param
  423. MONITOR_ENUM_PARAM* pParam = (MONITOR_ENUM_PARAM*)dwData;
  424. if(pParam)
  425. {
  426. // If a dest rect was passed
  427. if(pParam->pVirtualRect)
  428. {
  429. // If MONITOR_SEARCH_METOHD then we are being asked for the index of the monitor
  430. // that the rect falls inside of
  431. if(pParam->lFlags & MONITOR_SEARCH_METOHD)
  432. {
  433. if( (pParam->pVirtualRect->right < lprcMonitor->left) ||
  434. (pParam->pVirtualRect->left > lprcMonitor->right) ||
  435. (pParam->pVirtualRect->bottom < lprcMonitor->top) ||
  436. (pParam->pVirtualRect->top > lprcMonitor->bottom))
  437. {
  438. // Nothing
  439. }
  440. else
  441. {
  442. // This is the one
  443. pParam->iMonitor = pParam->nMonitorCount;
  444. // Stop the enumeration
  445. return FALSE;
  446. }
  447. }
  448. else
  449. {
  450. if(pParam->iMonitor == pParam->nMonitorCount)
  451. {
  452. *pParam->pVirtualRect = *lprcMonitor;
  453. }
  454. else
  455. if(pParam->iMonitor == -1)
  456. {
  457. pParam->pVirtualRect->left = min(pParam->pVirtualRect->left, lprcMonitor->left);
  458. pParam->pVirtualRect->top = min(pParam->pVirtualRect->top, lprcMonitor->top);
  459. pParam->pVirtualRect->right = max(pParam->pVirtualRect->right, lprcMonitor->right);
  460. pParam->pVirtualRect->bottom = max(pParam->pVirtualRect->bottom, lprcMonitor->bottom);
  461. }
  462. }
  463. }
  464. // Up the count if necessary
  465. pParam->nMonitorCount++;
  466. }
  467. return TRUE;
  468. }
  469. int GetScreenWidth(void)
  470. {
  471. OSVERSIONINFO OS_Version_Info;
  472. DWORD dwPlatform = 0;
  473. if(GetVersionEx(&OS_Version_Info) != 0)
  474. {
  475. dwPlatform = OS_Version_Info.dwPlatformId;
  476. }
  477. if(dwPlatform == VER_PLATFORM_WIN32_NT)
  478. {
  479. int width, height;
  480. width = GetSystemMetrics(SM_CXSCREEN);
  481. height = GetSystemMetrics(SM_CYSCREEN);
  482. switch(width)
  483. {
  484. default:
  485. case 640:
  486. case 800:
  487. case 1024:
  488. return(width);
  489. case 1280:
  490. if(height == 480)
  491. {
  492. return(width / 2);
  493. }
  494. return(width);
  495. case 1600:
  496. if(height == 600)
  497. {
  498. return(width / 2);
  499. }
  500. return(width);
  501. case 2048:
  502. if(height == 768)
  503. {
  504. return(width / 2);
  505. }
  506. return(width);
  507. }
  508. }
  509. else
  510. {
  511. return(GetSystemMetrics(SM_CXVIRTUALSCREEN));
  512. }
  513. }
  514. int GetScreenHeight(void)
  515. {
  516. OSVERSIONINFO OS_Version_Info;
  517. DWORD dwPlatform = 0;
  518. if(GetVersionEx(&OS_Version_Info) != 0)
  519. {
  520. dwPlatform = OS_Version_Info.dwPlatformId;
  521. }
  522. if(dwPlatform == VER_PLATFORM_WIN32_NT)
  523. {
  524. int width, height;
  525. width = GetSystemMetrics(SM_CXSCREEN);
  526. height = GetSystemMetrics(SM_CYSCREEN);
  527. switch(height)
  528. {
  529. default:
  530. case 480:
  531. case 600:
  532. case 768:
  533. return(height);
  534. case 960:
  535. if(width == 640)
  536. {
  537. return(height / 2);
  538. }
  539. return(height);
  540. case 1200:
  541. if(width == 800)
  542. {
  543. return(height / 2);
  544. }
  545. return(height);
  546. case 1536:
  547. if(width == 1024)
  548. {
  549. return(height / 2);
  550. }
  551. return(height);
  552. }
  553. }
  554. else
  555. {
  556. return(GetSystemMetrics(SM_CYVIRTUALSCREEN));
  557. }
  558. }
  559. int GetMonitorFromRect(LPRECT lpMonitorRect)
  560. {
  561. // Build up the param
  562. MONITOR_ENUM_PARAM EnumParam;
  563. ZeroMemory(&EnumParam, sizeof(EnumParam));
  564. EnumParam.lFlags = MONITOR_SEARCH_METOHD;
  565. EnumParam.pVirtualRect = lpMonitorRect;
  566. EnumParam.iMonitor = -1;
  567. // Enum Displays
  568. EnumDisplayMonitors(NULL, NULL, MyMonitorEnumProc, (LPARAM)&EnumParam);
  569. // Return the result
  570. return EnumParam.iMonitor;
  571. }
  572. void GetMonitorRect(int iMonitor, LPRECT lpDestRect)
  573. {
  574. // Build up the param
  575. MONITOR_ENUM_PARAM EnumParam;
  576. ZeroMemory(&EnumParam, sizeof(EnumParam));
  577. EnumParam.iMonitor = iMonitor;
  578. EnumParam.pVirtualRect = lpDestRect;
  579. // Zero out dest rect
  580. lpDestRect->bottom = lpDestRect->left = lpDestRect->right = lpDestRect->top = 0;
  581. // Enum Displays
  582. EnumDisplayMonitors(NULL, NULL, MyMonitorEnumProc, (LPARAM)&EnumParam);
  583. // If not successful, default to the screen dimentions
  584. if(lpDestRect->right == 0 || lpDestRect->bottom == 0)
  585. {
  586. lpDestRect->right = GetScreenWidth();
  587. lpDestRect->bottom = GetScreenHeight();
  588. }
  589. //adjust the rect for the taskbar
  590. APPBARDATA appBarData;
  591. appBarData.cbSize=sizeof(appBarData);
  592. if (SHAppBarMessage(ABM_GETTASKBARPOS, &appBarData))
  593. {
  594. switch(appBarData.uEdge)
  595. {
  596. case ABE_LEFT:
  597. lpDestRect->left += appBarData.rc.right - appBarData.rc.left;
  598. break;
  599. case ABE_RIGHT:
  600. lpDestRect->right -= appBarData.rc.right - appBarData.rc.left;
  601. break;
  602. case ABE_TOP:
  603. lpDestRect->top += appBarData.rc.bottom - appBarData.rc.top;
  604. break;
  605. case ABE_BOTTOM:
  606. lpDestRect->bottom -= appBarData.rc.bottom - appBarData.rc.top;
  607. break;
  608. }
  609. return;
  610. }
  611. }
  612. /*------------------------------------------------------------------*\
  613. ID based Globals
  614. \*------------------------------------------------------------------*/
  615. long NewGroupID(int parentID, CString text)
  616. {
  617. long lID=0;
  618. CTime time;
  619. time = CTime::GetCurrentTime();
  620. try
  621. {
  622. //sqlite doesn't like single quotes ' replace them with double ''
  623. if(text.IsEmpty())
  624. text = time.Format("NewGroup %y/%m/%d %H:%M:%S");
  625. text.Replace(_T("'"), _T("''"));
  626. CString cs;
  627. cs.Format(_T("insert into Main (lDate, mText, lDontAutoDelete, bIsGroup, lParentID, stickyClipOrder, stickyClipGroupOrder) values(%d, '%s', %d, 1, %d, -(2147483647), -(2147483647));"),
  628. (int)time.GetTime(),
  629. text,
  630. (int)time.GetTime(),
  631. parentID);
  632. theApp.m_db.execDML(cs);
  633. lID = (long)theApp.m_db.lastRowId();
  634. }
  635. CATCH_SQLITE_EXCEPTION_AND_RETURN(0)
  636. return lID;
  637. }
  638. BOOL DeleteAllIDs()
  639. {
  640. try
  641. {
  642. theApp.m_db.execDML(_T("DELETE FROM Data;"));
  643. theApp.m_db.execDML(_T("DELETE FROM Main;"));
  644. }
  645. CATCH_SQLITE_EXCEPTION
  646. return TRUE;
  647. }
  648. BOOL DeleteFormats(int parentID, ARRAY& formatIDs)
  649. {
  650. if(formatIDs.GetSize() <= 0)
  651. return TRUE;
  652. try
  653. {
  654. //Delete the requested data formats
  655. INT_PTR count = formatIDs.GetSize();
  656. for(int i = 0; i < count; i++)
  657. {
  658. int count = theApp.m_db.execDMLEx(_T("DELETE FROM Data WHERE lID = %d;"), formatIDs[i]);
  659. int k = 0;
  660. }
  661. CClip clip;
  662. if(clip.LoadFormats(parentID))
  663. {
  664. DWORD CRC = clip.GenerateCRC();
  665. //Update the main table with new size
  666. theApp.m_db.execDMLEx(_T("UPDATE Main SET CRC = %d WHERE lID = %d"), CRC, parentID);
  667. }
  668. }
  669. CATCH_SQLITE_EXCEPTION
  670. return TRUE;
  671. }
  672. CRect CenterRect(CRect startingRect)
  673. {
  674. CRect crMonitor;
  675. int nMonitor = GetMonitorFromRect(&startingRect);
  676. if(nMonitor < 0)
  677. {
  678. GetMonitorRect(0, crMonitor);
  679. }
  680. else
  681. {
  682. GetMonitorRect(nMonitor, crMonitor);
  683. }
  684. return CenterRectFromRect(startingRect, crMonitor);
  685. }
  686. CRect CenterRectFromRect(CRect startingRect, CRect outerRect)
  687. {
  688. CPoint center = outerRect.CenterPoint();
  689. CRect centerRect;
  690. centerRect.left = center.x - (startingRect.Width() / 2);
  691. centerRect.top = center.y - (startingRect.Height() / 2);
  692. centerRect.right = centerRect.left + startingRect.Width();
  693. centerRect.bottom = centerRect.top + startingRect.Height();
  694. return centerRect;
  695. }
  696. BOOL EnsureWindowVisible(CRect *pcrRect)
  697. {
  698. int nMonitor = GetMonitorFromRect(pcrRect);
  699. if(nMonitor < 0)
  700. {
  701. GetMonitorRect(0, pcrRect);
  702. pcrRect->right = pcrRect->left + 300;
  703. pcrRect->bottom = pcrRect->top + 300;
  704. return TRUE;
  705. }
  706. BOOL ret = FALSE;
  707. CRect crMonitor;
  708. GetMonitorRect(nMonitor, crMonitor);
  709. bool movedLeft = false;
  710. //Validate the left
  711. long lDiff = pcrRect->left - crMonitor.left;
  712. if(lDiff < 0)
  713. {
  714. pcrRect->left += abs(lDiff);
  715. pcrRect->right += abs(lDiff);
  716. ret = TRUE;
  717. movedLeft = true;
  718. }
  719. //Right side
  720. lDiff = pcrRect->right - crMonitor.right;
  721. if(lDiff > 0)
  722. {
  723. if(movedLeft == false)
  724. {
  725. pcrRect->left -= abs(lDiff);
  726. }
  727. pcrRect->right -= abs(lDiff);
  728. ret = TRUE;
  729. }
  730. bool movedTop = false;
  731. //Top
  732. lDiff = pcrRect->top - crMonitor.top;
  733. if(lDiff < 0)
  734. {
  735. pcrRect->top += abs(lDiff);
  736. pcrRect->bottom += abs(lDiff);
  737. ret = TRUE;
  738. movedTop = true;
  739. }
  740. //Bottom
  741. lDiff = pcrRect->bottom - crMonitor.bottom;
  742. if(lDiff > 0)
  743. {
  744. if(movedTop == false)
  745. {
  746. pcrRect->top -= abs(lDiff);
  747. }
  748. pcrRect->bottom -= abs(lDiff);
  749. ret = TRUE;
  750. }
  751. return ret;
  752. }
  753. __int64 GetLastWriteTime(const CString &csFile)
  754. {
  755. __int64 nLastWrite = 0;
  756. CFileFind finder;
  757. BOOL bResult = finder.FindFile(csFile);
  758. if (bResult)
  759. {
  760. finder.FindNextFile();
  761. FILETIME ft;
  762. finder.GetLastWriteTime(&ft);
  763. memcpy(&nLastWrite, &ft, sizeof(ft));
  764. }
  765. return nLastWrite;
  766. }
  767. typedef struct
  768. {
  769. DWORD ownerpid;
  770. DWORD childpid;
  771. } windowinfo;
  772. BOOL CALLBACK EnumChildWindowsCallback(HWND hWnd, LPARAM lp)
  773. {
  774. windowinfo* info = (windowinfo*)lp;
  775. DWORD pid = 0;
  776. GetWindowThreadProcessId(hWnd, &pid);
  777. if (pid != info->ownerpid)
  778. info->childpid = pid;
  779. return TRUE;
  780. }
  781. CString UWP_AppName(HWND active_window, DWORD ownerpid)
  782. {
  783. CString uwpAppName;
  784. windowinfo info = { 0 };
  785. info.ownerpid = ownerpid;
  786. info.childpid = info.ownerpid;
  787. EnumChildWindows(active_window, EnumChildWindowsCallback, (LPARAM)&info);
  788. HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info.childpid);
  789. if (active_process != NULL)
  790. {
  791. WCHAR image_name[MAX_PATH] = { 0 };
  792. DWORD bufsize = MAX_PATH;
  793. QueryFullProcessImageName(active_process, 0, image_name, &bufsize);
  794. CloseHandle(active_process);
  795. nsPath::CPath path(image_name);
  796. uwpAppName = path.GetName();
  797. }
  798. return uwpAppName;
  799. }
  800. CString GetProcessName(HWND hWnd, DWORD processId)
  801. {
  802. DWORD startTick = GetTickCount();
  803. CString strProcessName;
  804. DWORD Id = processId;
  805. if (Id == 0)
  806. {
  807. GetWindowThreadProcessId(hWnd, &Id);
  808. }
  809. HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, Id);
  810. if (active_process != NULL)
  811. {
  812. WCHAR image_name[MAX_PATH] = { 0 };
  813. DWORD bufsize = MAX_PATH;
  814. QueryFullProcessImageName(active_process, 0, image_name, &bufsize);
  815. CloseHandle(active_process);
  816. nsPath::CPath path(image_name);
  817. strProcessName = path.GetName();
  818. }
  819. /*PROCESSENTRY32 processEntry = { 0 };
  820. HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  821. processEntry.dwSize = sizeof(PROCESSENTRY32);
  822. if (Process32First(hSnapShot, &processEntry))
  823. {
  824. do
  825. {
  826. if (processEntry.th32ProcessID == Id)
  827. {
  828. strProcessName = processEntry.szExeFile;
  829. break;
  830. }
  831. } while(Process32Next(hSnapShot, &processEntry));
  832. }
  833. CloseHandle(hSnapShot);*/
  834. //uwp apps are wrapped in another app called, if this has focus then try and find the child uwp process
  835. if (strProcessName == _T("ApplicationFrameHost.exe"))
  836. {
  837. strProcessName = UWP_AppName(hWnd, Id);
  838. }
  839. DWORD endTick = GetTickCount();
  840. DWORD diff = endTick - startTick;
  841. if(diff > 5)
  842. {
  843. Log(StrF(_T("GetProcessName Time (ms): %d"), endTick-startTick));
  844. }
  845. return strProcessName;
  846. }
  847. BOOL IsVista()
  848. {
  849. OSVERSIONINFO osver;
  850. osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
  851. if (::GetVersionEx( &osver ) &&
  852. osver.dwPlatformId == VER_PLATFORM_WIN32_NT &&
  853. (osver.dwMajorVersion >= 6 ) )
  854. {
  855. return TRUE;
  856. }
  857. return FALSE;
  858. }
  859. bool IsRunningLimited()
  860. {
  861. LPCTSTR pszSubKey = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
  862. LPCTSTR pszValue = _T("EnableLUA");
  863. DWORD dwType = 0;
  864. DWORD dwValue = 0;
  865. DWORD dwValueSize = sizeof(DWORD);
  866. if(ERROR_SUCCESS != SHGetValue(HKEY_LOCAL_MACHINE, pszSubKey, pszValue, &dwType, &dwValue, &dwValueSize))
  867. {
  868. //failed to read the reg key, either it's not there or we don't have access to the registry
  869. //If we are vista then assume we don't have access and we are running as a limited app
  870. //otherwise we are xp and the reg key probably doesn't exist and we are not a limited running app
  871. if(IsVista())
  872. {
  873. OutputDebugString(_T("Ditto - Failed to read registry entry finding UAC, Running as limited application"));
  874. return true;
  875. }
  876. }
  877. if(dwValue == 1)
  878. {
  879. OutputDebugString(_T("Ditto - UAC ENABLED, Running as limited application"));
  880. return true;
  881. }
  882. OutputDebugString(_T("Ditto - Running as standard application"));
  883. return false;
  884. }
  885. void DeleteDittoTempFiles(BOOL checkFileLastAccess)
  886. {
  887. CString csDir = CGetSetOptions::GetPath(PATH_REMOTE_FILES);
  888. if (FileExists(csDir))
  889. {
  890. DeleteFolderFiles(csDir, checkFileLastAccess);
  891. }
  892. csDir = CGetSetOptions::GetPath(PATH_DRAG_FILES);
  893. if (FileExists(csDir))
  894. {
  895. DeleteFolderFiles(csDir, checkFileLastAccess);
  896. }
  897. csDir = CGetSetOptions::GetPath(PATH_CLIP_DIFF);
  898. if (FileExists(csDir))
  899. {
  900. DeleteFolderFiles(csDir, checkFileLastAccess);
  901. }
  902. }
  903. void DeleteFolderFiles(CString csDir, BOOL checkFileLastAccess)
  904. {
  905. if (csDir.Find(_T("\\ReceivedFiles\\")) == -1 && csDir.Find(_T("\\DragFiles\\")) == -1 && csDir.Find(_T("ClipCompare")) == -1)
  906. return;
  907. Log(StrF(_T("Deleting files in Folder %s Check Last Access %d"), csDir, checkFileLastAccess));
  908. FIX_CSTRING_PATH(csDir);
  909. CTime ctOld = CTime::GetCurrentTime();
  910. CTime ctFile;
  911. ctOld -= CTimeSpan(0, 0, 0, 1);
  912. CFileFind Find;
  913. CString csFindString;
  914. csFindString.Format(_T("%s*.*"), csDir);
  915. BOOL bFound = Find.FindFile(csFindString);
  916. while(bFound)
  917. {
  918. bFound = Find.FindNextFile();
  919. if(Find.IsDots())
  920. continue;
  921. if(Find.IsDirectory())
  922. {
  923. CString csDir(Find.GetFilePath());
  924. DeleteFolderFiles(csDir, checkFileLastAccess);
  925. RemoveDirectory(csDir);
  926. }
  927. if(checkFileLastAccess &&
  928. Find.GetLastAccessTime(ctFile))
  929. {
  930. //Delete the remote copied file if it hasn't been used for the last day
  931. if(ctFile < ctOld)
  932. {
  933. Log(StrF(_T("Deleting temp file %s"), Find.GetFilePath()));
  934. DeleteFile(Find.GetFilePath());
  935. }
  936. }
  937. else
  938. {
  939. Log(StrF(_T("Deleting temp file %s"), Find.GetFilePath()));
  940. DeleteFile(Find.GetFilePath());
  941. }
  942. }
  943. }
  944. __int64 FileSize(const TCHAR *fileName)
  945. {
  946. struct _stat64 buf;
  947. if (_wstat64((wchar_t const*)fileName, &buf) != 0)
  948. return -1; // error, could use errno to find out more
  949. return buf.st_size;
  950. }
  951. int FindNoCaseAndInsert(CString& mainStr, CString& findStr, CString preInsert, CString postInsert, int linesPerRow)
  952. {
  953. int replaceCount = 0;
  954. //Prevent infinite loop when user tries to replace nothing.
  955. if (findStr != "")
  956. {
  957. int oldLen = findStr.GetLength();
  958. int foundPos = 0;
  959. int startFindPos = 0;
  960. int newPos = 0;
  961. int insertedLength = 0;
  962. int firstFindPos = 0;
  963. //use icu::UnicodeString because it handles upper/lowercase characters for all languages, CSTring only hanldes ascii characters
  964. icu::UnicodeString mainLow(mainStr);
  965. mainLow.foldCase(U_FOLD_CASE_DEFAULT);
  966. icu::UnicodeString findLow(findStr);
  967. findLow.foldCase(U_FOLD_CASE_DEFAULT);
  968. int preLength = preInsert.GetLength();
  969. int postLength = postInsert.GetLength();
  970. int x = mainLow.indexOf(findLow, 0);
  971. while(TRUE)
  972. {
  973. foundPos = mainLow.indexOf(findLow, startFindPos);
  974. if (foundPos < 0)
  975. break;
  976. if (replaceCount == 0)
  977. {
  978. firstFindPos = foundPos + preLength;
  979. }
  980. newPos = foundPos + insertedLength;
  981. mainStr.Insert(newPos, preInsert);
  982. mainStr.Insert(newPos + preLength + oldLen, postInsert);
  983. startFindPos = foundPos + oldLen;
  984. insertedLength += preLength + postLength;
  985. replaceCount++;
  986. //safety check, make sure we don't look forever
  987. if (replaceCount > 100)
  988. break;
  989. }
  990. startFindPos = 0;
  991. int line = 0;
  992. int prevLinePos = 0;
  993. int prevPrevLinePos = 0;
  994. while (TRUE)
  995. {
  996. foundPos = mainStr.Find(_T("\n"), startFindPos);
  997. if (foundPos < 0)
  998. break;
  999. if (firstFindPos < foundPos)
  1000. {
  1001. if (line > linesPerRow - 1)
  1002. {
  1003. int lineStart = prevLinePos;
  1004. if (linesPerRow > 1)
  1005. {
  1006. lineStart = prevPrevLinePos;
  1007. }
  1008. mainStr = _T("... ") + mainStr.Mid(lineStart + 1);
  1009. }
  1010. break;
  1011. }
  1012. startFindPos = foundPos + 1;
  1013. prevPrevLinePos = prevLinePos;
  1014. prevLinePos = foundPos;
  1015. line++;
  1016. //safety check, make sure we don't look forever
  1017. if (line > 1000)
  1018. break;
  1019. }
  1020. if(replaceCount > 0)
  1021. {
  1022. //use unprintable characters so it doesn't find copied html to convert
  1023. mainStr.Replace(_T("\r\n"), _T("\x01\x05\x02"));
  1024. int l = mainStr.Replace(_T("\r"), _T("\x01\x05\x02"));
  1025. int m = mainStr.Replace(_T("\n"), _T("\x01\x05\x02"));
  1026. }
  1027. }
  1028. return replaceCount;
  1029. }
  1030. void OnInitMenuPopupEx(CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu, CWnd *pWnd)
  1031. {
  1032. ASSERT(pPopupMenu != NULL);
  1033. // Check the enabled state of various menu items.
  1034. CCmdUI state;
  1035. state.m_pMenu = pPopupMenu;
  1036. ASSERT(state.m_pOther == NULL);
  1037. ASSERT(state.m_pParentMenu == NULL);
  1038. // Determine if menu is popup in top-level menu and set m_pOther to
  1039. // it if so (m_pParentMenu == NULL indicates that it is secondary popup).
  1040. HMENU hParentMenu;
  1041. if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu)
  1042. {
  1043. state.m_pParentMenu = pPopupMenu; // Parent == child for tracking popup.
  1044. }
  1045. else if ((hParentMenu = ::GetMenu(pWnd->m_hWnd)) != NULL)
  1046. {
  1047. CWnd* pParent = pWnd;
  1048. // Child windows don't have menus--need to go to the top!
  1049. if (pParent != NULL &&
  1050. (hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
  1051. {
  1052. int nIndexMax = ::GetMenuItemCount(hParentMenu);
  1053. for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
  1054. {
  1055. if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu)
  1056. {
  1057. // When popup is found, m_pParentMenu is containing menu.
  1058. state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
  1059. break;
  1060. }
  1061. }
  1062. }
  1063. }
  1064. state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
  1065. for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
  1066. state.m_nIndex++)
  1067. {
  1068. state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
  1069. if (state.m_nID == 0)
  1070. continue; // Menu separator or invalid cmd - ignore it.
  1071. ASSERT(state.m_pOther == NULL);
  1072. ASSERT(state.m_pMenu != NULL);
  1073. if (state.m_nID == (UINT)-1)
  1074. {
  1075. // Possibly a popup menu, route to first item of that popup.
  1076. state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
  1077. if (state.m_pSubMenu == NULL ||
  1078. (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
  1079. state.m_nID == (UINT)-1)
  1080. {
  1081. continue; // First item of popup can't be routed to.
  1082. }
  1083. state.DoUpdate(pWnd, TRUE); // Popups are never auto disabled.
  1084. }
  1085. else
  1086. {
  1087. // Normal menu item.
  1088. // Auto enable/disable if frame window has m_bAutoMenuEnable
  1089. // set and command is _not_ a system command.
  1090. state.m_pSubMenu = NULL;
  1091. state.DoUpdate(pWnd, FALSE);
  1092. }
  1093. // Adjust for menu deletions and additions.
  1094. UINT nCount = pPopupMenu->GetMenuItemCount();
  1095. if (nCount < state.m_nIndexMax)
  1096. {
  1097. state.m_nIndex -= (state.m_nIndexMax - nCount);
  1098. while (state.m_nIndex < nCount &&
  1099. pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
  1100. {
  1101. state.m_nIndex++;
  1102. }
  1103. }
  1104. state.m_nIndexMax = nCount;
  1105. }
  1106. }
  1107. CString InternetEncode(CString text)
  1108. {
  1109. CString ret = _T("");
  1110. LPTSTR lpOutputBuffer = new TCHAR[1];
  1111. DWORD dwSize = 1;
  1112. BOOL fRes = ::InternetCanonicalizeUrl(text, lpOutputBuffer, &dwSize, ICU_DECODE | ICU_NO_ENCODE);
  1113. DWORD dwError = ::GetLastError();
  1114. if (!fRes && dwError == ERROR_INSUFFICIENT_BUFFER)
  1115. {
  1116. delete lpOutputBuffer;
  1117. lpOutputBuffer = new TCHAR[dwSize];
  1118. fRes = ::InternetCanonicalizeUrl(text, lpOutputBuffer, &dwSize, ICU_DECODE | ICU_NO_ENCODE);
  1119. if (fRes)
  1120. {
  1121. ret = lpOutputBuffer;
  1122. //lpOutputBuffer has decoded url
  1123. }
  1124. else
  1125. {
  1126. //failed to decode
  1127. }
  1128. if (lpOutputBuffer != NULL)
  1129. {
  1130. delete [] lpOutputBuffer;
  1131. lpOutputBuffer = NULL;
  1132. }
  1133. }
  1134. else
  1135. {
  1136. //some other error OR the input string url is just 1 char and was successfully decoded
  1137. }
  1138. return ret;
  1139. }
  1140. void DeleteParamFromRTF(CStringA &test, CStringA find, bool searchForTrailingDigits)
  1141. {
  1142. int start = 0;
  1143. while (start >= 0)
  1144. {
  1145. start = test.Find(find, start);
  1146. if (start >= 0)
  1147. {
  1148. if (start > 0)
  1149. {
  1150. //leave it if the preceding character is \\, i was seeing the double slash if the actual text contained slash
  1151. if (test[start - 1] == '\\')
  1152. {
  1153. start++;
  1154. continue;
  1155. }
  1156. }
  1157. int end = -1;
  1158. int innerStart = start + find.GetLength();
  1159. if (searchForTrailingDigits)
  1160. {
  1161. for (int i = innerStart; i < test.GetLength(); i++)
  1162. {
  1163. if (isdigit(test[i]) == false)
  1164. {
  1165. end = i;
  1166. break;
  1167. }
  1168. }
  1169. }
  1170. else
  1171. {
  1172. end = innerStart;
  1173. }
  1174. if (end > 0)
  1175. {
  1176. if (searchForTrailingDigits == false ||
  1177. end != innerStart)
  1178. {
  1179. test.Delete(start, (end - start));
  1180. }
  1181. else
  1182. {
  1183. start++;
  1184. }
  1185. }
  1186. else
  1187. {
  1188. break;
  1189. }
  1190. }
  1191. }
  1192. }
  1193. bool RemoveRTFSection(CStringA &str, CStringA section)
  1194. {
  1195. bool removedSection = false;
  1196. int start2 = str.Find(section, 0);
  1197. int end2 = 0;
  1198. if (start2 >= 0)
  1199. {
  1200. int in = 0;
  1201. for (int pos = start2+1; pos < str.GetLength(); pos++)
  1202. {
  1203. if (str[pos] == '{')
  1204. {
  1205. in++;
  1206. }
  1207. if (str[pos] == '}')
  1208. {
  1209. if (in > 0)
  1210. {
  1211. in--;
  1212. }
  1213. else
  1214. {
  1215. end2 = pos;
  1216. break;
  1217. }
  1218. }
  1219. }
  1220. if (end2 > start2)
  1221. {
  1222. str.Delete(start2, (end2 - start2) + 1);
  1223. removedSection = true;
  1224. }
  1225. }
  1226. return removedSection;
  1227. }
  1228. CString NewGuidString()
  1229. {
  1230. CString guidString;
  1231. GUID guid;
  1232. CoCreateGuid(&guid);
  1233. guidString.Format(_T("%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX"),
  1234. guid.Data1, guid.Data2, guid.Data3,
  1235. guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
  1236. guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
  1237. return guidString;
  1238. }