FuncHelper.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Version : 2.3.15
  5. * Author : Bruce Liang
  6. * Website : http://www.jessma.org
  7. * Project : https://github.com/ldcsaa
  8. * Blog : http://www.cnblogs.com/ldcsaa
  9. * Wiki : http://www.oschina.net/p/hp-socket
  10. * QQ Group : 75375912
  11. *
  12. * Licensed under the Apache License, Version 2.0 (the "License");
  13. * you may not use this file except in compliance with the License.
  14. * You may obtain a copy of the License at
  15. *
  16. * http://www.apache.org/licenses/LICENSE-2.0
  17. *
  18. * Unless required by applicable law or agreed to in writing, software
  19. * distributed under the License is distributed on an "AS IS" BASIS,
  20. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21. * See the License for the specific language governing permissions and
  22. * limitations under the License.
  23. */
  24. #include "stdafx.h"
  25. #include "FuncHelper.h"
  26. #include "WaitFor.h"
  27. #ifndef _WIN32_WCE
  28. #define CloseToolhelp32Snapshot(h) CloseHandle(h)
  29. #include <psapi.h>
  30. #include <Shellapi.h>
  31. #pragma comment(lib, "Psapi")
  32. #else
  33. #pragma comment(lib, "Toolhelp")
  34. #endif
  35. BYTE DoubleCharToByte(LPCTSTR psValue)
  36. {
  37. return (BYTE)DOUBLECHARTOVALUE(psValue);
  38. }
  39. LPTSTR ByteToDoubleChar(BYTE b, LPTSTR des)
  40. {
  41. VALUETODOUBLECHAR(des, b);
  42. return des;
  43. }
  44. UINT HexStrToInt(LPCTSTR pHexText, int len)
  45. {
  46. LPTSTR pTemp = (LPTSTR)pHexText;
  47. int Val = 0;
  48. int iLen = lstrlen(pHexText);
  49. if(len > 0 && len < iLen)
  50. iLen = len;
  51. if(iLen % 2)
  52. {
  53. pTemp = (TCHAR*)_alloca(sizeof(TCHAR) * ((++iLen) + 1));
  54. lstrcpyn(pTemp+1, pHexText, iLen);
  55. pTemp[0] = '0';
  56. }
  57. for(int i = 0; i < iLen; i+=2)
  58. Val += (DOUBLECHARTOVALUE(&pTemp[i]) << ((iLen - i)/2 - 1) * 8);
  59. return Val;
  60. }
  61. UINT DecStrToInt(LPCTSTR pDecText, int len)
  62. {
  63. int Val = 0;
  64. int iLen = lstrlen(pDecText);
  65. if(len > 0 && len < iLen)
  66. {
  67. ++len;
  68. CString text;
  69. LPTSTR ptext = text.GetBuffer(len);
  70. lstrcpyn(ptext, pDecText, len);
  71. Val = _ttol(ptext);
  72. text.ReleaseBuffer();
  73. }
  74. else
  75. Val = _ttol(pDecText);
  76. return Val;
  77. }
  78. CString& IntToHexStr(CString& dest, UINT v, int len)
  79. {
  80. if(len > 0)
  81. {
  82. CString format;
  83. format.Format(_T("%%0%uX"), len);
  84. dest.Format(format, v);
  85. if(dest.GetLength() > len)
  86. dest = dest.Right(len);
  87. }
  88. else
  89. dest.Format(_T("%X"), v);
  90. return dest;
  91. }
  92. CString& IntToDecStr(CString& dest, UINT v, int len)
  93. {
  94. if(len > 0)
  95. {
  96. CString format;
  97. format.Format(_T("%%0%uu"), len);
  98. dest.Format(format, v);
  99. if(dest.GetLength() > len)
  100. dest = dest.Right(len);
  101. }
  102. else
  103. dest.Format(_T("%u"), v);
  104. return dest;
  105. }
  106. CString& HexAddrToDecAddr(CString& dest, LPCTSTR src, int destlen, int srclen)
  107. {
  108. return IntToDecStr(dest, HexStrToInt(src, srclen), destlen);
  109. }
  110. CString& DecAddrToHexAddr(CString& dest, LPCTSTR src, int destlen, int srclen)
  111. {
  112. return IntToHexStr(dest, DecStrToInt(src, srclen), destlen);
  113. }
  114. //-----------------------------MultiByte×Ö·ûºÍUnicode×Ö·ûÖ®¼äµÄת»»-----------------------------//
  115. EnCodePage GetCodePageByName(LPCTSTR lpszCodePageName)
  116. {
  117. if(!lpszCodePageName || !*lpszCodePageName)
  118. return XCP_ACP;
  119. else if(_tcsicmp(lpszCodePageName, _T("GB2312")) == 0)
  120. return XCP_GB2312;
  121. else if(_tcsicmp(lpszCodePageName, _T("GBK")) == 0)
  122. return XCP_GBK;
  123. else if(_tcsicmp(lpszCodePageName, _T("UTF-8")) == 0)
  124. return XCP_UTF8;
  125. else if(_tcsicmp(lpszCodePageName, _T("UTF-7")) == 0)
  126. return XCP_UTF7;
  127. else if(_tcsicmp(lpszCodePageName, _T("BIG5")) == 0)
  128. return XCP_BIG5;
  129. return XCP_ACP;
  130. }
  131. BOOL MbcsToUnicode(const char* pszInString, WCHAR** ptrOutWStr, int& nSizeCount)
  132. {
  133. return CPToUni(pszInString, ptrOutWStr, CP_ACP, nSizeCount);
  134. }
  135. BOOL UnicodeToMbcs(const WCHAR* pwzInString, char** ptrOutStr, int& nSizeCount)
  136. {
  137. return UniToCP(pwzInString, ptrOutStr, CP_ACP, nSizeCount);
  138. }
  139. BOOL Utf8ToUnicode(const char* pszInString, WCHAR** ptrOutWStr, int& nSizeCount)
  140. {
  141. return CPToUni(pszInString, ptrOutWStr, CP_UTF8, nSizeCount);
  142. }
  143. BOOL UnicodeToUtf8(const WCHAR* pwzInString, char** ptrOutStr, int& nSizeCount)
  144. {
  145. return UniToCP(pwzInString, ptrOutStr, CP_UTF8, nSizeCount);
  146. }
  147. BOOL CPToUni(const char* pszInString, WCHAR** ptrOutWStr, unsigned int nCodePage, int& nSizeCount)
  148. {
  149. nSizeCount = 0 ;
  150. if( pszInString == nullptr || ptrOutWStr == nullptr )
  151. return FALSE ;
  152. nSizeCount = MultiByteToWideChar( nCodePage, 0, pszInString, -1, nullptr, 0 ) ;
  153. if( 0 == nSizeCount )
  154. return FALSE ;
  155. (*ptrOutWStr) = new WCHAR[nSizeCount] ;
  156. if( nullptr == (*ptrOutWStr) )
  157. return FALSE ;
  158. if( 0 == MultiByteToWideChar( nCodePage, 0, pszInString, -1, (*ptrOutWStr), nSizeCount ) )
  159. {
  160. delete[] (*ptrOutWStr);
  161. return FALSE ;
  162. }
  163. return TRUE;
  164. }
  165. BOOL UniToCP(const WCHAR* pwzInString, char** ptrOutStr, unsigned int nCodePage, int& nSizeCount)
  166. {
  167. nSizeCount = 0 ;
  168. if( pwzInString == nullptr || ptrOutStr == nullptr )
  169. return FALSE ;
  170. nSizeCount = WideCharToMultiByte( nCodePage, 0, pwzInString, -1, nullptr, 0, nullptr, nullptr) ;
  171. if( 0 == nSizeCount )
  172. return FALSE ;
  173. (*ptrOutStr) = new char[nSizeCount] ;
  174. if( nullptr == (*ptrOutStr) )
  175. return FALSE ;
  176. if(0 == WideCharToMultiByte( nCodePage, 0, pwzInString, -1, (*ptrOutStr), nSizeCount, nullptr, nullptr))
  177. {
  178. delete[] (*ptrOutStr);
  179. return FALSE ;
  180. }
  181. return TRUE;
  182. }
  183. int BytesToHex(const BYTE* pBytes, int nLength, LPTSTR* lpszDest)
  184. {
  185. int des_length = nLength * 2;
  186. if(des_length > 0)
  187. {
  188. LPTSTR dest = new TCHAR[des_length + 1];
  189. dest[des_length] = '\0';
  190. TCHAR chs[3] = {0};
  191. for(int i = 0; i < nLength; i++)
  192. {
  193. ByteToDoubleChar(pBytes[i], chs);
  194. dest[2 * i] = chs[0];
  195. dest[2 * i + 1] = chs[1];
  196. }
  197. *lpszDest = dest;
  198. }
  199. else
  200. *lpszDest = nullptr;
  201. return des_length;
  202. }
  203. int HexToBytes(LPCTSTR lpszHex, BYTE** ppBytes, int* pnLength)
  204. {
  205. int src_length = lstrlen(lpszHex);
  206. int des_length = src_length / 2;
  207. *pnLength = des_length;
  208. if(des_length > 0)
  209. {
  210. BYTE* pBytes = new BYTE[des_length];
  211. for(int i = 0; i < des_length; i++)
  212. pBytes[i] = DoubleCharToByte(&lpszHex[2 * i]);
  213. *ppBytes = pBytes;
  214. }
  215. else
  216. *ppBytes = nullptr;
  217. return des_length;
  218. }
  219. CString& StrToHex(const TCHAR* src, CString& strDec)
  220. {
  221. BYTE* t = (BYTE*)src;
  222. int src_length = lstrlen(src) * sizeof(TCHAR);
  223. strDec.Empty();
  224. #ifdef UNICODE
  225. char* temp = nullptr;
  226. UnicodeToMbcs(src, &temp, src_length);
  227. src_length -= 1;
  228. t = (BYTE*)temp;
  229. #else
  230. t = (BYTE*)src;
  231. src_length = lstrlen(src);
  232. #endif
  233. for(int i = 0; i < src_length; ++i, ++t)
  234. {
  235. TCHAR tc[3] = {0, 0, 0};
  236. VALUETODOUBLECHAR(tc, *t);
  237. strDec += tc;
  238. }
  239. #ifdef UNICODE
  240. delete[] temp;
  241. #endif
  242. return strDec;
  243. }
  244. CString& HexToStr(const TCHAR* src, CString& strDec)
  245. {
  246. char* temp = nullptr;
  247. int src_length = 0;
  248. strDec.Empty();
  249. #ifdef UNICODE
  250. char* temp1 = new char[(src_length = lstrlen(src)) +1];
  251. temp = temp1;
  252. while(*(temp1++) = (char)*(src++));
  253. #else
  254. temp = (char*)src;
  255. src_length = lstrlen(src);
  256. //t = strDec.GetBuffer(src_length/2 + 1);
  257. #endif
  258. int i=0;
  259. for(; i < src_length / 2; ++i)
  260. {
  261. temp[i] = DOUBLECHARTOVALUE(temp + 2 * i);
  262. }
  263. temp[i] = 0;
  264. #ifdef UNICODE
  265. int iLen = 0;
  266. WCHAR* wh = nullptr;
  267. MbcsToUnicode(temp, &wh, iLen);
  268. strDec = wh;
  269. delete[] wh;
  270. delete[] temp;
  271. #else
  272. strDec.ReleaseBuffer();
  273. #endif
  274. return strDec;
  275. }
  276. CString& StrToUtf8Hex(const TCHAR* src, CString& strDec)
  277. {
  278. char* t = nullptr;
  279. WCHAR* temp = nullptr;
  280. int src_length = 0;
  281. strDec.Empty();
  282. #ifndef UNICODE
  283. MbcsToUnicode(src, &temp, src_length);
  284. #else
  285. temp = (TCHAR*)src;
  286. #endif
  287. UnicodeToUtf8(temp, &t, src_length);
  288. src_length -= 1;
  289. for(int i = 0; i < src_length; ++i)
  290. {
  291. TCHAR tc[3] = {0, 0, 0};
  292. VALUETODOUBLECHAR(tc, t[i]);
  293. strDec += tc;
  294. }
  295. #ifndef UNICODE
  296. delete[] temp;
  297. #endif
  298. delete[] t;
  299. return strDec;
  300. }
  301. CString& HexUtf8ToStr(const TCHAR* src, CString& strDec)
  302. {
  303. char* temp = nullptr;
  304. WCHAR* pwsz = nullptr;
  305. int iLen = 0;
  306. int src_length = 0;
  307. strDec.Empty();
  308. #ifdef UNICODE
  309. char* temp1 = new char[(src_length = lstrlen(src)) +1];
  310. temp = temp1;
  311. while(*(temp1++) = (char)*(src++));
  312. #else
  313. temp = (char*)src;
  314. src_length = lstrlen(src);
  315. #endif
  316. int i=0;
  317. for(; i < src_length / 2; ++i)
  318. {
  319. temp[i] = DOUBLECHARTOVALUE(temp + 2*i);
  320. }
  321. temp[i] = 0;
  322. Utf8ToUnicode(temp, &pwsz, iLen);
  323. #ifdef UNICODE
  324. strDec = pwsz;
  325. delete[] temp;
  326. #else
  327. char* psz = nullptr;
  328. UnicodeToMbcs(pwsz, &psz, iLen);
  329. strDec = psz;
  330. delete[] psz;
  331. #endif
  332. delete[] pwsz;
  333. return strDec;
  334. }
  335. CString GetSystemErrorDesc(DWORD dwCode)
  336. {
  337. CString msg;
  338. LPTSTR lpMsgBuf;
  339. if(::FormatMessage(
  340. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  341. nullptr,
  342. dwCode,
  343. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  344. (LPTSTR)&lpMsgBuf,
  345. 0,
  346. nullptr
  347. ))
  348. {
  349. msg = lpMsgBuf;
  350. ::LocalFree(lpMsgBuf);
  351. }
  352. return msg;
  353. }
  354. BOOL SplitStr(LPCTSTR pszSrc, vector<CString>& vtItem, LPCTSTR pszSepectors, LPCTSTR pszQMarks)
  355. {
  356. vtItem.clear();
  357. CString strQMarks = pszQMarks;
  358. CString strSepectors = pszSepectors;
  359. if(strSepectors.IsEmpty())
  360. strSepectors = _T(" ");
  361. if(!strQMarks.IsEmpty())
  362. if(strQMarks.FindOneOf(strSepectors) != -1)
  363. return FALSE;
  364. BOOL bRetVal = TRUE;
  365. CString strSrc = pszSrc;
  366. while(!strSrc.Trim(strSepectors).IsEmpty())
  367. {
  368. CString strItem;
  369. int iSrcLen = strSrc.GetLength();
  370. int iPos1 = strSrc.FindOneOf(strSepectors);
  371. int iPos2 = !strQMarks.IsEmpty() ? strSrc.FindOneOf(strQMarks) : -1;
  372. int iPos3 = -1;
  373. if(iPos1 == -1 && iPos2 == -1)
  374. strItem = strSrc;
  375. else if(iPos1 != -1 && (iPos1 < iPos2 || iPos2 == -1))
  376. strItem = strSrc.Left(iPos1);
  377. else // (iPos1 > iPos2 || iPos1 == -1)
  378. {
  379. TCHAR tc = strSrc[iPos2];
  380. iPos3 = strSrc.Find(tc, iPos2 + 1);
  381. if(iPos3 != -1)
  382. strItem = strSrc.Mid(iPos2 + 1, iPos3 - iPos2 - 1);
  383. else
  384. {
  385. vtItem.clear();
  386. bRetVal = FALSE;
  387. break;
  388. }
  389. }
  390. vtItem.push_back(strItem);
  391. strSrc = strSrc.Right(iPos3 == -1 ? (iSrcLen - (iPos1 == -1 ? strItem.GetLength() : iPos1 + 1)) : (iSrcLen - iPos3 - 1));
  392. }
  393. return bRetVal;
  394. }
  395. CString ExtractFileName(LPCTSTR lpszFullFileName)
  396. {
  397. CString strPath = lpszFullFileName;
  398. strPath.Trim();
  399. if(!strPath.IsEmpty())
  400. {
  401. int iLen = strPath.GetLength();
  402. int iLastSep = strPath.ReverseFind(PATH_SEPARATOR_CHAR);
  403. if(iLastSep != -1)
  404. strPath = strPath.Right(iLen - 1 - iLastSep);
  405. }
  406. return strPath;
  407. }
  408. CString ExtractPath(LPCTSTR lpszFullFileName)
  409. {
  410. CString strPath = lpszFullFileName;
  411. strPath.Trim();
  412. if(strPath.IsEmpty())
  413. return PATH_SEPARATOR;
  414. int iLen = strPath.GetLength();
  415. int iLastSep = strPath.ReverseFind(PATH_SEPARATOR_CHAR);
  416. int iLastDot = strPath.ReverseFind(FILE_EXTEND_SEPARATOR_CHAR);
  417. if(iLastSep == -1 && iLastDot == -1)
  418. strPath.Append(PATH_SEPARATOR);
  419. else if(iLastSep == -1 && iLastDot != -1)
  420. strPath = PATH_SEPARATOR;
  421. else if(iLastSep > iLastDot)
  422. {
  423. if(iLastSep < iLen)
  424. strPath.Append(PATH_SEPARATOR);
  425. }
  426. else
  427. {
  428. strPath = strPath.Left(iLastSep + 1);
  429. }
  430. return strPath;
  431. }
  432. CString ExtractModulePath(HMODULE hModule)
  433. {
  434. CString strCurPath;
  435. LPTSTR lpszCurPath = strCurPath.GetBuffer(MAX_PATH);
  436. BOOL isOK = ::GetModuleFileName(hModule, lpszCurPath, MAX_PATH);
  437. strCurPath.ReleaseBuffer();
  438. if(isOK)
  439. {
  440. strCurPath = ::ExtractPath(strCurPath);
  441. ASSERT(!strCurPath.IsEmpty());
  442. }
  443. return strCurPath;
  444. }
  445. BOOL RunProcess(LPCTSTR szFileName, LPCTSTR cmdline/* = nullptr*/, BOOL bHide /* = TRUE */, LPCTSTR dir /* = nullptr*/, BOOL bWait /* = TRUE */, DWORD dwWaitTime /* = INFINITE */)
  446. {
  447. LPCTSTR process_dir;
  448. if (dir == nullptr || _tcslen(dir) == 0)
  449. process_dir = nullptr;
  450. else
  451. process_dir = dir;
  452. LPCTSTR process_name;
  453. if (szFileName == nullptr || _tcslen(szFileName) == 0)
  454. process_name = nullptr;
  455. else
  456. process_name = szFileName;
  457. STARTUPINFO si;
  458. ZeroMemory(&si, sizeof(si));
  459. si.cb = sizeof(si);
  460. DWORD dwCreationFlags = 0;
  461. if (bHide)
  462. {
  463. si.wShowWindow = SW_HIDE;
  464. #ifndef _WIN32_WCE
  465. dwCreationFlags = CREATE_NO_WINDOW;
  466. #endif
  467. }
  468. PROCESS_INFORMATION pi;
  469. ZeroMemory(&pi, sizeof(pi));
  470. // Start the child process
  471. CString strCmd(cmdline);
  472. LPTSTR pszcmd = (LPTSTR)(LPCTSTR)strCmd;
  473. BOOL bRet = CreateProcess(
  474. process_name,
  475. pszcmd, // Command line.
  476. nullptr, // Process handle not inheritable.
  477. nullptr, // Thread handle not inheritable.
  478. FALSE, // Set handle inheritance to FALSE.
  479. dwCreationFlags, // No creation flags.
  480. nullptr, // Use parent's environment block.
  481. (LPTSTR)process_dir, // Use parent's starting directory.
  482. &si, // Pointer to STARTUPINFO structure.
  483. &pi
  484. );
  485. if(bRet)
  486. {
  487. if(bWait)
  488. bRet = (::WaitForSingleObject(pi.hProcess, dwWaitTime) != WAIT_FAILED) ? TRUE : FALSE;
  489. ::CloseHandle(pi.hProcess);
  490. ::CloseHandle(pi.hThread);
  491. }
  492. return bRet;
  493. }
  494. BOOL ShellRunExe(LPCTSTR lpszPath, LPCTSTR lpszParams, int iShow, HANDLE* phProcess, BOOL bWait, DWORD dwWaitTime)
  495. {
  496. CString strPath = lpszPath;
  497. strPath.Trim();
  498. ASSERT(strPath.GetLength() > 4 && strPath.Right(4).CompareNoCase(EXE_FILE_EXTEND_NAME) == 0);
  499. #ifdef _WIN32_WCE
  500. if(strPath.GetAt(0) != PATH_SEPARATOR_CHAR)
  501. #else
  502. if(strPath.GetAt(1) != DISK_SYMBLE_CHAR)
  503. #endif
  504. {
  505. CString strCurPath = ExtractModulePath();
  506. strPath = strCurPath + strPath;
  507. }
  508. SHELLEXECUTEINFO info = {0};
  509. info.cbSize = sizeof(SHELLEXECUTEINFO);
  510. info.lpFile = strPath;
  511. info.fMask = SEE_MASK_FLAG_NO_UI;
  512. info.nShow = iShow;
  513. info.lpParameters = lpszParams;
  514. if(phProcess || bWait)
  515. info.fMask |= SEE_MASK_NOCLOSEPROCESS;
  516. BOOL isOK = FALSE;
  517. if(::ShellExecuteEx(&info))
  518. {
  519. if(phProcess)
  520. *phProcess = info.hProcess;
  521. if(bWait)
  522. {
  523. isOK = (::WaitForSingleObject(info.hProcess, dwWaitTime) != WAIT_FAILED) ? TRUE : FALSE;
  524. ::CloseHandle(info.hProcess);
  525. }
  526. else
  527. isOK = TRUE;
  528. }
  529. return isOK;
  530. }
  531. void WriteLog(LPCTSTR pszLogFileName, LPCTSTR pszLog)
  532. {
  533. #ifdef _UNICODE
  534. USES_CONVERSION;
  535. #endif
  536. HANDLE hLogFile = ::CreateFile(pszLogFileName, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
  537. if(hLogFile != INVALID_HANDLE_VALUE)
  538. ::SetFilePointer(hLogFile, 0, 0, FILE_END);
  539. else
  540. return;
  541. DWORD dwSize;
  542. SYSTEMTIME st;
  543. GetLocalTime(&st);
  544. CString strLog;
  545. strLog.Format(_T("[%02d-%02d %02d:%02d:%02d.%03d] %s\r\n"), st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, pszLog);
  546. #ifdef _UNICODE
  547. LPSTR lpszLog = T2A((LPTSTR)(LPCTSTR)strLog);
  548. ::WriteFile(hLogFile, lpszLog, (DWORD)::strlen(lpszLog), &dwSize, nullptr);
  549. #else
  550. ::WriteFile(hLogFile, strLog, strLog.GetLength(), &dwSize, nullptr);
  551. #endif
  552. ::CloseHandle(hLogFile);
  553. }
  554. BOOL FindProcess(LPCTSTR pszProcessName)
  555. {
  556. BOOL isOK = FALSE;
  557. HANDLE hTool = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  558. if(hTool != INVALID_HANDLE_VALUE)
  559. {
  560. PROCESSENTRY32 pe32;
  561. pe32.dwSize = sizeof(PROCESSENTRY32);
  562. if(::Process32First(hTool, &pe32))
  563. {
  564. do
  565. {
  566. if(_tcsicmp(pszProcessName, pe32.szExeFile) == 0)
  567. {
  568. isOK = TRUE;
  569. break;
  570. }
  571. } while(::Process32Next(hTool, &pe32));
  572. }
  573. VERIFY(::CloseToolhelp32Snapshot(hTool));
  574. }
  575. return isOK;
  576. }
  577. HANDLE FindProcessHandle(LPCTSTR pszProcessName, DWORD dwDesiredAccess, BOOL bInheritHandle)
  578. {
  579. HANDLE hProc = nullptr;
  580. HANDLE hTool = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  581. if(hTool != INVALID_HANDLE_VALUE)
  582. {
  583. PROCESSENTRY32 pe32;
  584. pe32.dwSize = sizeof(PROCESSENTRY32);
  585. if(::Process32First(hTool, &pe32))
  586. {
  587. do
  588. {
  589. if(_tcsicmp(pszProcessName, pe32.szExeFile) == 0)
  590. {
  591. hProc = ::OpenProcess(dwDesiredAccess, bInheritHandle, pe32.th32ProcessID);
  592. break;
  593. }
  594. } while(::Process32Next(hTool, &pe32));
  595. }
  596. VERIFY(::CloseToolhelp32Snapshot(hTool));
  597. }
  598. return hProc;
  599. }
  600. BOOL FindRunningProcessesInfo(ProcessInfoMap& infoMap)
  601. {
  602. infoMap.Clear();
  603. HANDLE hProc = nullptr;
  604. HANDLE hTool = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  605. if(hTool != INVALID_HANDLE_VALUE)
  606. {
  607. PROCESSENTRY32 pe32;
  608. pe32.dwSize = sizeof(PROCESSENTRY32);
  609. if(::Process32First(hTool, &pe32))
  610. {
  611. do
  612. {
  613. PROCESSENTRY32* ppe32 = new PROCESSENTRY32;
  614. memcpy(ppe32, &pe32, sizeof(PROCESSENTRY32));
  615. infoMap[pe32.th32ProcessID] = ppe32;
  616. } while(::Process32Next(hTool, &pe32));
  617. }
  618. VERIFY(::CloseToolhelp32Snapshot(hTool));
  619. }
  620. else
  621. return FALSE;
  622. return TRUE;
  623. }
  624. #ifndef _WIN32_WCE
  625. BOOL FindProcessEx(LPCTSTR pszProcessName)
  626. {
  627. BOOL bRet = FALSE;
  628. DWORD aProcesses[1024], cbNeeded, cProcesses;
  629. if (::EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
  630. {
  631. cProcesses = cbNeeded / sizeof(DWORD);
  632. for (DWORD i = 0; i < cProcesses; i++)
  633. {
  634. HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);
  635. if (hProcess)
  636. {
  637. HMODULE hMod;
  638. DWORD cbNeeded;
  639. if (::EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
  640. {
  641. TCHAR szProcessName[MAX_PATH] = {0};
  642. if(::GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName)))
  643. {
  644. if(_tcsicmp(szProcessName, pszProcessName) == 0)
  645. {
  646. DWORD dwExitCode = 0;
  647. if(::GetExitCodeProcess(hProcess, &dwExitCode) && dwExitCode == STILL_ACTIVE)
  648. {
  649. bRet = TRUE;
  650. break;
  651. }
  652. }
  653. }
  654. }
  655. ::CloseHandle( hProcess );
  656. }
  657. }
  658. }
  659. return bRet;
  660. }
  661. CString GetIniString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpFileName, DWORD dwSize)
  662. {
  663. CString strValue;
  664. LPTSTR pszBuffer = strValue.GetBuffer(dwSize);
  665. ::GetPrivateProfileString(lpAppName, lpKeyName, _T(""), pszBuffer, dwSize, lpFileName);
  666. strValue.ReleaseBuffer();
  667. strValue.Trim();
  668. return strValue;
  669. }
  670. BOOL SetCurrentPathToModulePath(HMODULE hModule)
  671. {
  672. TCHAR szPath[MAX_PATH];
  673. if(::GetModuleFileName(hModule, szPath, MAX_PATH))
  674. {
  675. TCHAR drive[MAX_PATH], dir[MAX_PATH], fname[MAX_PATH], ext[MAX_PATH];
  676. _tsplitpath(szPath, drive, dir, fname, ext);
  677. lstrcpy(szPath, drive);
  678. lstrcat(szPath, dir);
  679. return ::SetCurrentDirectory(szPath);
  680. }
  681. return FALSE;
  682. }
  683. #endif
  684. struct TProcWnd
  685. {
  686. DWORD dwProcID;
  687. LPCTSTR lpszClassName;
  688. HWND hWnd;
  689. };
  690. BOOL CALLBACK ProcessMainWindowEnumFunc(HWND hwnd, LPARAM lParam)
  691. {
  692. TProcWnd* ppw = (TProcWnd*)lParam;
  693. DWORD dwProcID;
  694. ::GetWindowThreadProcessId(hwnd, &dwProcID);
  695. if(dwProcID == ppw->dwProcID)
  696. {
  697. while(TRUE)
  698. {
  699. HWND hwParent = ::GetParent(hwnd);
  700. if(hwParent == nullptr)
  701. {
  702. if(ppw->lpszClassName == nullptr)
  703. {
  704. ppw->hWnd = hwnd;
  705. return FALSE;
  706. }
  707. else
  708. {
  709. int nMaxCount = MAX_PATH - 1;
  710. TCHAR szName[MAX_PATH] = {0};
  711. if(::GetClassName(hwnd, szName, nMaxCount))
  712. {
  713. if(_tcscmp(szName, ppw->lpszClassName) == 0)
  714. {
  715. ppw->hWnd = hwnd;
  716. return FALSE;
  717. }
  718. }
  719. }
  720. break;
  721. }
  722. else
  723. hwnd = hwParent;
  724. }
  725. }
  726. return TRUE;
  727. }
  728. HWND FindProcessMainWindow(DWORD dwProcID, LPCTSTR lpszWndClassName)
  729. {
  730. if(dwProcID == 0)
  731. dwProcID = ::GetCurrentProcessId();
  732. ASSERT(dwProcID != 0);
  733. TProcWnd pw;
  734. pw.dwProcID = dwProcID;
  735. pw.lpszClassName = lpszWndClassName;
  736. pw.hWnd = nullptr;
  737. ::EnumWindows(ProcessMainWindowEnumFunc, (LPARAM)&pw);
  738. return pw.hWnd;
  739. }
  740. HWND FindProcessMainWindow(HANDLE hProcess, LPCTSTR lpszWndClassName)
  741. {
  742. DWORD dwProcID = (hProcess == nullptr) ? ::GetCurrentProcessId() : ::GetProcessId(hProcess);
  743. if(dwProcID != 0)
  744. return FindProcessMainWindow(dwProcID, lpszWndClassName);
  745. return nullptr;
  746. }
  747. BOOL CALLBACK CloseWindowEnumFunc(HWND hwnd, LPARAM lParam)
  748. {
  749. DWORD dwProcID;
  750. ::GetWindowThreadProcessId(hwnd, &dwProcID);
  751. if(dwProcID == (DWORD)lParam)
  752. ::PostMessage(hwnd, WM_CLOSE, 0, 0);
  753. return TRUE;
  754. }
  755. BOOL TerminateProcessFairily(HANDLE hProcess, DWORD dwWait)
  756. {
  757. DWORD dwProcID = ::GetProcessId(hProcess);
  758. if(dwProcID != 0)
  759. {
  760. VERIFY(::EnumWindows(CloseWindowEnumFunc, (LPARAM)dwProcID));
  761. if(!::MsgWaitForSingleObject(hProcess, dwWait))
  762. return ::TerminateProcess(hProcess, -1);
  763. return TRUE;
  764. }
  765. return FALSE;
  766. }
  767. #ifdef _AFX
  768. CString SecondToTimeStr(DWORD dwSeconds, BOOL bDayOnly)
  769. {
  770. CTime tm(dwSeconds);
  771. LPCTSTR pszFormat = bDayOnly ? _T("%Y-%m-%d") : _T("%Y-%m-%d %H:%M:%S");
  772. return tm.Format(pszFormat);
  773. }
  774. #endif
  775. BOOL GetRegistryValue(HKEY hRoot, LPCTSTR wcSubKey, LPCTSTR wcName, LPBYTE pValue, DWORD* pdwSize, DWORD* pdwType)
  776. {
  777. DWORD result = ERROR_INVALID_DATA;
  778. CRegKey reg;
  779. result = reg.Create(hRoot, wcSubKey, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ);
  780. if(result == ERROR_SUCCESS)
  781. result = reg.QueryValue(wcName, pdwType, pValue, pdwSize);
  782. BOOL isOK = (result == ERROR_SUCCESS);
  783. if(!isOK)
  784. {
  785. *pValue = 0;
  786. *pdwSize = 0;
  787. *pdwType = REG_NONE;
  788. }
  789. return isOK;
  790. }
  791. BOOL SetRegistryValue(HKEY hRoot, LPCTSTR wcSubKey, LPCTSTR wcName, LPBYTE pValue, DWORD dwSize, DWORD dwType)
  792. {
  793. DWORD result = ERROR_INVALID_DATA;
  794. CRegKey reg;
  795. result = reg.Create(hRoot, wcSubKey);
  796. if(result == ERROR_SUCCESS)
  797. result = reg.SetValue(wcName, dwType, pValue, dwSize);
  798. return (result == ERROR_SUCCESS);
  799. }