开源的socket服务端客户端,支持C# C++

FuncHelper.cpp 20KB

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