Global.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. #include "StdAfx.h"
  2. #include "Global.h"
  3. // 获取文件版本号函数头文件;
  4. #include <WinVer.h>
  5. #pragma comment(lib,"version.lib")
  6. using namespace std;
  7. TCHAR g_szModulePath[MAX_PATH] = _T(""); // 软件目录;
  8. TCHAR g_szModuleFileName[MAX_PATH] = _T(""); // 软件名称;
  9. TCHAR g_szIniFile[MAX_PATH] = _T("");
  10. // 配置文件信息;
  11. TCHAR g_szServAddress[MAX_PATH] = _T("");
  12. DWORD g_dwServPort = 0;
  13. TCHAR g_szAccount[MAX_PATH] = _T("");
  14. TCHAR g_szPassword[MAX_PATH] = _T("");
  15. TCHAR g_szWeChatPath[MAX_PATH] = _T("");
  16. TCHAR g_szCacheDir[MAX_PATH] = _T("");
  17. TCHAR g_szDynamicLibraryPath[MAX_PATH] = _T("");
  18. // 控制台输出;
  19. BOOL g_bStdOut = FALSE;
  20. /************************************************************************/
  21. /* 函数:[1/6/2019 Home];
  22. /* 描述:;
  23. /* 参数:;
  24. /* [IN] :;
  25. /* [OUT] :;
  26. /* [IN/OUT] :;
  27. /* 返回:void;
  28. /* 注意:;
  29. /* 示例:;
  30. /*
  31. /* 修改:;
  32. /* 日期:;
  33. /* 内容:;
  34. /************************************************************************/
  35. int GetIniInfo(LPCTSTR lpIniDir /* = NULL */, LPCTSTR lpIniName /* = NULL */)
  36. {
  37. TCHAR szDrive[_MAX_DRIVE] = { 0 };
  38. TCHAR szDir[_MAX_DIR] = { 0 };
  39. TCHAR szFna[_MAX_DIR] = { 0 };
  40. TCHAR szExt[_MAX_DIR] = { 0 };
  41. ::GetModuleFileName(NULL, g_szModulePath, sizeof(g_szModulePath) / sizeof(TCHAR));
  42. swprintf_s(g_szModuleFileName, _T("%s"), g_szModulePath);
  43. _tsplitpath_s(g_szModulePath, szDrive, szDir, szFna, szExt);
  44. _tcscpy_s(g_szModulePath, szDrive);
  45. _tcscat_s(g_szModulePath, szDir);
  46. // 动态库路径;
  47. _stprintf_s(g_szDynamicLibraryPath, _T("%shook.dll"), g_szModulePath);
  48. if (lpIniDir != NULL && lpIniName != NULL)
  49. _stprintf_s(g_szIniFile, _T("%s%s"), lpIniDir, lpIniName);
  50. else
  51. _stprintf_s(g_szIniFile, _T("%sconfig.ini"), g_szModulePath);
  52. HANDLE hFile = CreateFile(g_szIniFile, 0/*GENERIC_READ*/, 0, NULL, OPEN_EXISTING, 0, NULL);
  53. if (ERROR_FILE_NOT_FOUND == GetLastError())
  54. {
  55. return -1;
  56. }
  57. CloseHandle(hFile);
  58. hFile = NULL;
  59. // 获取服务器端信息;
  60. GetPrivateProfileString(_T("ServerInfo"), _T("IP"), _T(""), g_szServAddress, MAX_PATH, g_szIniFile);
  61. g_dwServPort = GetPrivateProfileInt(_T("ServerInfo"), _T("Port"), 0, g_szIniFile);
  62. GetPrivateProfileString(_T("CustomerInfo"), _T("Account"), _T(""), g_szAccount, MAX_PATH, g_szIniFile);
  63. GetPrivateProfileString(_T("CustomerInfo"), _T("Password"), _T(""), g_szPassword, MAX_PATH, g_szIniFile);
  64. GetPrivateProfileString(_T("CustomerInfo"), _T("WeChat"), _T(""), g_szWeChatPath, MAX_PATH, g_szIniFile);
  65. GetPrivateProfileString(_T("CustomerInfo"), _T("Cache"), _T(""), g_szCacheDir, MAX_PATH, g_szIniFile);
  66. g_bStdOut = GetPrivateProfileInt(_T("CustomerInfo"), _T("StdOut"), 0, g_szIniFile);
  67. if ( g_bStdOut )
  68. {
  69. AllocConsole(); // 开辟控制台;
  70. SetConsoleTitle(_T("调试输出")); // 设置控制台窗口标题;
  71. freopen("CONOUT$", "w+t", stdout); // 重定向输出;
  72. freopen("CONIN$", "r+t", stdin); // 重定向输入;
  73. HWND hWnd = NULL;
  74. again:
  75. hWnd = ::FindWindow(NULL, _T("调试输出"));
  76. if( hWnd )
  77. {
  78. if (!::SetWindowPos(hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE))
  79. {
  80. _tprintf_s(_T("前置设置失败\n"));
  81. }
  82. else
  83. {
  84. _tprintf_s(_T("前置设置成功\n"));
  85. }
  86. }
  87. else
  88. {
  89. goto again;
  90. }
  91. }
  92. return 0;
  93. }
  94. /************************************************************************/
  95. /* 函数:[1/6/2019 Home];
  96. /* 描述:;
  97. /* 参数:;
  98. /* [IN] :;
  99. /* [OUT] :;
  100. /* [IN/OUT] :;
  101. /* 返回:void;
  102. /* 注意:;
  103. /* 示例:;
  104. /*
  105. /* 修改:;
  106. /* 日期:;
  107. /* 内容:;
  108. /************************************************************************/
  109. DWORD FindProcess(LPCTSTR lpProName)
  110. {
  111. ASSERT(lpProName!=NULL);
  112. DWORD dwPID = 0;
  113. PROCESSENTRY32 pe32 = { 0 };
  114. HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  115. if (hSnapshot == NULL)
  116. {
  117. return 0;
  118. }
  119. pe32.dwSize = sizeof(PROCESSENTRY32);
  120. if (Process32First(hSnapshot, &pe32))
  121. {
  122. do {
  123. if (_tcsicmp(lpProName, pe32.szExeFile) == 0)
  124. {
  125. dwPID = pe32.th32ProcessID;
  126. break;
  127. }
  128. } while (Process32Next(hSnapshot, &pe32));
  129. }
  130. CloseHandle(hSnapshot);
  131. return dwPID;
  132. }
  133. vector<DWORD> FindAllProcess(LPCTSTR lpProName)
  134. {
  135. ASSERT(lpProName!=NULL);
  136. vector<DWORD> vtPID;
  137. PROCESSENTRY32 pe32 = { 0 };
  138. HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  139. if (hSnapshot == NULL)
  140. return vector<DWORD>();
  141. pe32.dwSize = sizeof(PROCESSENTRY32);
  142. if (Process32First(hSnapshot, &pe32))
  143. {
  144. do {
  145. if (_tcsicmp(lpProName, pe32.szExeFile) == 0)
  146. {
  147. vtPID.push_back(pe32.th32ProcessID);
  148. }
  149. } while (Process32Next(hSnapshot, &pe32));
  150. }
  151. CloseHandle(hSnapshot);
  152. return vtPID;
  153. }
  154. MODULEENTRY32 FindModule(LPCTSTR lpModuleName, DWORD dwPID)
  155. {
  156. ASSERT(lpModuleName!=NULL);
  157. DWORD dwMID = 0;
  158. MODULEENTRY32 me32 = { 0 };
  159. HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
  160. if (hSnapshot == NULL)
  161. return me32;
  162. me32.dwSize = sizeof(PROCESSENTRY32);
  163. if (Module32First(hSnapshot, &me32))
  164. {
  165. do {
  166. if (_tcsicmp(lpModuleName, me32.szModule) == 0)
  167. {
  168. break;
  169. }
  170. } while (Module32Next(hSnapshot, &me32));
  171. }
  172. CloseHandle(hSnapshot);
  173. return me32;
  174. }
  175. // WINDOWS NT 以上的内核需要提权,才能对系统进行高级管理;
  176. /************************************************************************/
  177. /* 函数:[1/6/2019 Home];
  178. /* 描述:;
  179. /* 参数:;
  180. /* [IN] :;
  181. /* [OUT] :;
  182. /* [IN/OUT] :;
  183. /* 返回:void;
  184. /* 注意:;
  185. /* 示例:;
  186. /*
  187. /* 修改:;
  188. /* 日期:;
  189. /* 内容:;
  190. /************************************************************************/
  191. BOOL GetDebugPriv()
  192. {
  193. // 返回的访问令牌指针;
  194. HANDLE hToken;
  195. // 接收所返回的制定特权名称的信息;
  196. LUID sedebugnameValue;
  197. // 新特权信息的指针(结构体);
  198. TOKEN_PRIVILEGES tkp;
  199. DWORD dwCurProcId = GetCurrentProcessId();
  200. // 要修改访问权限的进程句柄;
  201. HANDLE hCurProc;
  202. hCurProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwCurProcId);
  203. if (!::OpenProcessToken(hCurProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  204. {
  205. //ShowSystemErrorInfo(_T("升级包OpenProcessToken失败."),GetLastError());
  206. return FALSE;
  207. }
  208. if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
  209. {
  210. //ShowSystemErrorInfo(_T("升级包LookupPrivilegeValue失败."),GetLastError());
  211. CloseHandle(hToken);
  212. return FALSE;
  213. }
  214. tkp.PrivilegeCount = 1;
  215. tkp.Privileges[0].Luid = sedebugnameValue;
  216. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  217. if (!::AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
  218. {
  219. //ShowSystemErrorInfo(_T("升级包AdjustTokenPrivileges失败."),GetLastError());
  220. CloseHandle(hToken);
  221. return FALSE;
  222. }
  223. CloseHandle(hCurProc);
  224. CloseHandle(hToken);
  225. return TRUE;
  226. }
  227. /************************************************************************/
  228. /*
  229. 函数:GetFileVersion
  230. 描述:获取可执行文件的文件版号;
  231. 参数:
  232. hModule[IN] 可执行文件模块句柄;
  233. dwArray[OUT] 返回的文件版本号;
  234. 返回:
  235. 成功返回TRUE,失败返回FALSE;
  236. 注意:
  237. 当hModule为空时,表示要获取的可执行文件为本程序的文件版本号;
  238. */
  239. /************************************************************************/
  240. BOOL GetFileVersion( IN HMODULE hModule, OUT DWORD (&dwArray)[4])
  241. {
  242. TCHAR fname[MAX_PATH];
  243. VS_FIXEDFILEINFO *pVi;
  244. DWORD dwHandle;
  245. if ( GetModuleFileName(hModule, fname, MAX_PATH))
  246. {
  247. INT nSize = GetFileVersionInfoSize(fname, &dwHandle);
  248. if (nSize > 0)
  249. {
  250. BYTE *pBuffer = new BYTE[nSize];
  251. memset(pBuffer, 0, nSize);
  252. if (GetFileVersionInfo(fname, dwHandle, nSize, pBuffer))
  253. {
  254. if (VerQueryValue(pBuffer, _T("\\"), (LPVOID *)&pVi, (PUINT)&nSize))
  255. {
  256. dwArray[0] = HIWORD(pVi->dwFileVersionMS);
  257. dwArray[1] = LOWORD(pVi->dwFileVersionMS);
  258. dwArray[2] = HIWORD(pVi->dwFileVersionLS);
  259. dwArray[3] = LOWORD(pVi->dwFileVersionLS);
  260. delete[]pBuffer;
  261. return TRUE;
  262. }
  263. }
  264. if ( pBuffer )
  265. delete[]pBuffer;
  266. }
  267. }
  268. return FALSE;
  269. }
  270. /************************************************************************/
  271. /*
  272. 函数:GetFileVersion
  273. 描述:获取可执行文件的文件版号;
  274. 参数:
  275. lpFileName[IN] 可执行文件名全路径;
  276. dwArray[OUT] 返回的文件版本号;
  277. 返回:
  278. 成功返回TRUE,失败返回FALSE;
  279. 注意:
  280. */
  281. /************************************************************************/
  282. BOOL GetFileVersionEx( IN LPCTSTR lpFileName, IN DWORD (&dwArray)[4] )
  283. {
  284. if ( lpFileName == NULL || !PathFileExists(lpFileName) )
  285. {
  286. OutputDebugString(_T("文件名错误或文件不存在\n"));
  287. return FALSE;
  288. }
  289. DWORD dwHandle = 0;
  290. VS_FIXEDFILEINFO *pVi = NULL;
  291. INT nSize = GetFileVersionInfoSize(lpFileName, &dwHandle);
  292. if ( nSize > 0 )
  293. {
  294. BYTE *pBuffer = new BYTE[nSize];
  295. memset(pBuffer, 0, nSize);
  296. if ( GetFileVersionInfo(lpFileName, dwHandle, nSize, pBuffer) )
  297. {
  298. if (VerQueryValue(pBuffer, _T("\\"), (LPVOID *)&pVi, (PUINT)&nSize))
  299. {
  300. dwArray[0] = HIWORD(pVi->dwFileVersionMS);
  301. dwArray[1] = LOWORD(pVi->dwFileVersionMS);
  302. dwArray[2] = HIWORD(pVi->dwFileVersionLS);
  303. dwArray[3] = LOWORD(pVi->dwFileVersionLS);
  304. if (pBuffer)
  305. delete[]pBuffer;
  306. return TRUE;
  307. }
  308. }
  309. if (pBuffer)
  310. delete[]pBuffer;
  311. }
  312. return FALSE;
  313. }
  314. /************************************************************************/
  315. /*
  316. 函数:GetProductVersion
  317. 描述:获取可执行文件的产品版号;
  318. 参数:
  319. hModule[IN] 可执行文件模块句柄;
  320. dwArray[OUT] 返回的产品版本号;
  321. 返回:
  322. 成功返回TRUE,失败返回FALSE;
  323. 注意:
  324. 当hModule为空时,表示要获取的可执行文件为本程序的产品版本号;
  325. */
  326. /************************************************************************/
  327. BOOL GetProductVersion(IN HMODULE hModule, IN DWORD (&dwArray)[4] )
  328. {
  329. TCHAR fname[MAX_PATH];
  330. VS_FIXEDFILEINFO *pVi;
  331. DWORD dwHandle;
  332. if (::GetModuleFileName(hModule, fname, MAX_PATH))
  333. {
  334. INT nSize = GetFileVersionInfoSize(fname, &dwHandle);
  335. if (nSize > 0)
  336. {
  337. BYTE *pBuffer = new BYTE[nSize];
  338. memset(pBuffer, 0, nSize);
  339. if (GetFileVersionInfo(fname, dwHandle, nSize, pBuffer))
  340. {
  341. if (VerQueryValue(pBuffer, _T("\\"), (LPVOID *)&pVi, (PUINT)&nSize))
  342. {
  343. dwArray[0] = HIWORD(pVi->dwProductVersionMS);
  344. dwArray[1] = LOWORD(pVi->dwProductVersionMS);
  345. dwArray[2] = HIWORD(pVi->dwProductVersionLS);
  346. dwArray[3] = LOWORD(pVi->dwProductVersionLS);
  347. if(pBuffer)
  348. delete[]pBuffer;
  349. return TRUE;
  350. }
  351. }
  352. if(pBuffer)
  353. delete[]pBuffer;
  354. }
  355. }
  356. return FALSE;
  357. }
  358. /************************************************************************/
  359. /*
  360. 函数:GetProductVersion
  361. 描述:获取可执行文件的产品版号;
  362. 参数:
  363. lpFileName[IN] 可执行文件名全路径;
  364. dwArray[OUT] 返回的产品版本号;
  365. 返回:
  366. 成功返回TRUE,失败返回FALSE;
  367. 注意:
  368. */
  369. /************************************************************************/
  370. BOOL GetProductVersionEx( IN LPCTSTR lpFileName, IN DWORD (&dwArray)[4] )
  371. {
  372. if ( lpFileName == NULL || !PathFileExists(lpFileName) )
  373. {
  374. OutputDebugString(_T("文件名错误或文件不存在\n"));
  375. return FALSE;
  376. }
  377. DWORD dwHandle = 0;
  378. VS_FIXEDFILEINFO *pVi = NULL;
  379. INT nSize = GetFileVersionInfoSize(lpFileName, &dwHandle);
  380. if ( nSize > 0 )
  381. {
  382. BYTE *pBuffer = new BYTE[nSize];
  383. memset(pBuffer, 0, nSize);
  384. if ( GetFileVersionInfo(lpFileName, dwHandle, nSize, pBuffer) )
  385. {
  386. if (VerQueryValue(pBuffer, _T("\\"), (LPVOID *)&pVi, (PUINT)&nSize))
  387. {
  388. dwArray[0] = HIWORD(pVi->dwProductVersionMS);
  389. dwArray[1] = LOWORD(pVi->dwProductVersionMS);
  390. dwArray[2] = HIWORD(pVi->dwProductVersionLS);
  391. dwArray[3] = LOWORD(pVi->dwProductVersionLS);
  392. if (pBuffer)
  393. delete[]pBuffer;
  394. return TRUE;
  395. }
  396. }
  397. if (pBuffer)
  398. delete[]pBuffer;
  399. }
  400. return FALSE;
  401. }
  402. /************************************************************************/
  403. /* 函数:WriteTextLog[7/28/2016 IT];
  404. /* 描述:写文本日志;
  405. /* 参数:;
  406. /* [IN] :;
  407. /* 返回:void;
  408. /* 注意:;
  409. /* 示例:;
  410. /*
  411. /* 修改:;
  412. /* 日期:;
  413. /* 内容:;
  414. /************************************************************************/
  415. void WriteTextLog(const TCHAR *format, ...)
  416. {
  417. try
  418. {
  419. //static ThreadSection _critSection;
  420. //AutoThreadSection aSection(&_critSection);
  421. // 解析出日志路径;
  422. TCHAR szlogpath[MAX_PATH] = {0};
  423. static TCHAR szModulePath[MAX_PATH] = {0};
  424. static TCHAR szFna[_MAX_DIR] = { 0 };
  425. if ( szModulePath[0] == _T('\0') )
  426. {
  427. TCHAR szDrive[_MAX_DRIVE] = { 0 };
  428. TCHAR szDir[_MAX_DIR] = { 0 };
  429. TCHAR szExt[_MAX_DIR] = { 0 };
  430. ::GetModuleFileName(NULL, szModulePath, sizeof(szModulePath) / sizeof(TCHAR));
  431. _tsplitpath_s(szModulePath, szDrive, szDir, szFna, szExt);
  432. _tcscpy_s(szModulePath, szDrive);
  433. _tcscat_s(szModulePath, szDir);
  434. }
  435. _stprintf_s(szlogpath, _T("%s日志\\%s%s.txt"), szModulePath, szFna, CTime::GetCurrentTime().Format("[%Y-%m-%d]"));
  436. // 打开或创建文件;
  437. CStdioFile fp;
  438. if (PathFileExists(szlogpath))
  439. {
  440. if (fp.Open(szlogpath, CFile::modeWrite) == FALSE)
  441. {
  442. return;
  443. }
  444. fp.SeekToEnd();
  445. }
  446. else
  447. {
  448. fp.Open(szlogpath, CFile::modeCreate | CFile::modeWrite);
  449. }
  450. // 格式化前设置语言区域;
  451. TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
  452. _tsetlocale(LC_CTYPE, _T("chs"));//设定中文;
  453. // 格式化日志内容;
  454. va_list args = NULL;
  455. int len = 0;
  456. TCHAR *buffer = NULL;
  457. va_start( args, format );
  458. // _vscprintf doesn't count. terminating '\0'
  459. len = _vsctprintf( format, args ) + 1;
  460. buffer = (TCHAR*)malloc( len * sizeof(TCHAR) );
  461. _vstprintf_s( buffer, len, format, args ); // C4996
  462. // Note: vsprintf is deprecated; consider using vsprintf_s instead
  463. // 将日志内容输入到文件中;
  464. fp.WriteString( CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S ")) );
  465. fp.WriteString(buffer);
  466. fp.WriteString(_T("\n"));
  467. // 关闭文件,释放资源并设置回原语言区域;
  468. free( buffer );
  469. _tsetlocale(LC_CTYPE, old_locale);
  470. free(old_locale);//还原区域设定;
  471. fp.Close();
  472. }
  473. catch (CException *e)
  474. {
  475. e->ReportError();
  476. e->Delete();
  477. }
  478. }
  479. //---------------------------------------------------------------------
  480. // add by Jeff 2014.10.27
  481. // 函数:全局函数IsDirectoryLegitimate,多字节版本,非UNICODE
  482. // 描述:判断一个目录路径字符串,是否属于合法的、可创建的目录路径。
  483. // 参数:strDirectory 被验证的路径字符串;
  484. //
  485. // 返回:合法路径返回TRUE;
  486. //---------------------------------------------------------------------
  487. BOOL IsDirectoryLegitimate(const CString &strDirectory)
  488. {
  489. if (strDirectory.Find('/') != -1 ||
  490. strDirectory.Find('\\') != -1 ||
  491. strDirectory.Find(':') != -1 ||
  492. strDirectory.Find('*') != -1 ||
  493. strDirectory.Find('?') != -1 ||
  494. strDirectory.Find('\"') != -1 ||
  495. strDirectory.Find('>') != -1 ||
  496. strDirectory.Find('<') != -1 ||
  497. strDirectory.Find('|') != -1
  498. )
  499. return FALSE;
  500. return TRUE;
  501. }
  502. //--------------------------------------------------------------------------------
  503. // Jeff add 2014.06.23;
  504. // 函数:ErrorExit
  505. // 描述:
  506. // 参数:
  507. // lpszFunction:函数名;
  508. // dwError:错误码;
  509. //
  510. //--------------------------------------------------------------------------------
  511. void ShowSystemErrorInfo(CString strDescription, const DWORD &dwError)
  512. {
  513. #if 1
  514. LPVOID lpMsgBuf;
  515. BOOL fOk = FormatMessage(
  516. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  517. FORMAT_MESSAGE_FROM_SYSTEM |
  518. FORMAT_MESSAGE_IGNORE_INSERTS,
  519. NULL,
  520. dwError,
  521. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  522. (LPTSTR)&lpMsgBuf,
  523. 0, NULL);
  524. if (!fOk)
  525. {
  526. // Is it a network-related error?
  527. HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);
  528. if (hDll != NULL)
  529. {
  530. FormatMessage(
  531. FORMAT_MESSAGE_FROM_HMODULE |
  532. FORMAT_MESSAGE_FROM_SYSTEM |
  533. FORMAT_MESSAGE_IGNORE_INSERTS,
  534. hDll,
  535. dwError,
  536. MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  537. (LPTSTR)&lpMsgBuf,
  538. 0,
  539. NULL);
  540. FreeLibrary(hDll);
  541. }
  542. }
  543. if (lpMsgBuf != NULL)
  544. {
  545. CString strDisplay;
  546. strDisplay.Format(_T("%s.错误码=%d,Windows描述:%s"), strDescription, dwError, (PCTSTR)LocalLock(lpMsgBuf));
  547. //WriteLog(strDisplay);
  548. LocalFree(lpMsgBuf);
  549. }
  550. else
  551. {
  552. //WriteLog(strDescription);
  553. }
  554. #else
  555. HLOCAL hlocal = NULL; // Buffer that gets the error message string
  556. // Get the error code's textual description
  557. BOOL fOk = FormatMessage(
  558. FORMAT_MESSAGE_FROM_SYSTEM |
  559. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  560. FORMAT_MESSAGE_IGNORE_INSERTS,
  561. NULL,
  562. dwError,
  563. MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  564. (PTSTR)&hlocal,
  565. 0,
  566. NULL);
  567. if (!fOk)
  568. {
  569. // Is it a network-related error?
  570. HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);
  571. if (hDll != NULL)
  572. {
  573. FormatMessage(
  574. FORMAT_MESSAGE_FROM_HMODULE |
  575. FORMAT_MESSAGE_FROM_SYSTEM |
  576. FORMAT_MESSAGE_IGNORE_INSERTS,
  577. hDll,
  578. dwError,
  579. MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  580. (PTSTR)&hlocal,
  581. 0,
  582. NULL);
  583. FreeLibrary(hDll);
  584. }
  585. }
  586. if (hlocal != NULL)
  587. {
  588. CString strDisplay;
  589. strDisplay.Format("%s 失败错误码=%d,Windows系统描述:%s", strDescription, dwError, (PCTSTR)LocalLock(hlocal));
  590. //WriteLog(strDisplay);
  591. LocalFree(hlocal);
  592. }
  593. else
  594. {
  595. //WriteLog("Error number not found.");
  596. }
  597. #endif
  598. }
  599. // The system displays a dialog box with a custom message and a message to the user to close applications within the specified time-out interval (30 seconds).
  600. // After the time-out interval elapses, the system is restarted.
  601. //The application must enable the SE_SHUTDOWN_NAME privilege before calling InitiateSystemShutdown
  602. BOOL MySystemShutdown(LPTSTR lpMsg)
  603. {
  604. HANDLE hToken; // handle to process token
  605. TOKEN_PRIVILEGES tkp; // pointer to token structure
  606. BOOL fResult; // system shutdown flag
  607. // Get the current process token handle so we can get shutdown
  608. // privilege.
  609. if (!OpenProcessToken(GetCurrentProcess(),
  610. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  611. return FALSE;
  612. // Get the LUID for shutdown privilege.
  613. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
  614. &tkp.Privileges[0].Luid);
  615. tkp.PrivilegeCount = 1; // one privilege to set
  616. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  617. // Get shutdown privilege for this process.
  618. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
  619. (PTOKEN_PRIVILEGES)NULL, 0);
  620. // Cannot test the return value of AdjustTokenPrivileges.
  621. if (GetLastError() != ERROR_SUCCESS)
  622. return FALSE;
  623. // Display the shutdown dialog box and start the countdown.
  624. fResult = InitiateSystemShutdown(
  625. NULL, // shut down local computer
  626. lpMsg, // message for user
  627. 30, // time-out period, in seconds
  628. FALSE, // ask user to close apps
  629. TRUE); // reboot after shutdown
  630. if (!fResult)
  631. return FALSE;
  632. // Disable shutdown privilege.
  633. tkp.Privileges[0].Attributes = 0;
  634. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
  635. (PTOKEN_PRIVILEGES)NULL, 0);
  636. return TRUE;
  637. }
  638. // If the AbortSystemShutdown function is executed in the time-out period specified by InitiateSystemShutdown,
  639. // the system does not shut down. For example, if PreventSystemShutdown is called after MySystemShutdown,
  640. // the system closes the dialog box and does not restart the system.
  641. BOOL PreventSystemShutdown()
  642. {
  643. HANDLE hToken; // handle to process token
  644. TOKEN_PRIVILEGES tkp; // pointer to token structure
  645. // Get the current process token handle so we can get shutdown
  646. // privilege.
  647. if (!OpenProcessToken(GetCurrentProcess(),
  648. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  649. return FALSE;
  650. // Get the LUID for shutdown privilege.
  651. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
  652. &tkp.Privileges[0].Luid);
  653. tkp.PrivilegeCount = 1; // one privilege to set
  654. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  655. // Get shutdown privilege for this process.
  656. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
  657. (PTOKEN_PRIVILEGES)NULL, 0);
  658. if (GetLastError() != ERROR_SUCCESS)
  659. return FALSE;
  660. // Prevent the system from shutting down.
  661. if (!AbortSystemShutdown(NULL))
  662. return FALSE;
  663. // Disable shutdown privilege.
  664. tkp.Privileges[0].Attributes = 0;
  665. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
  666. (PTOKEN_PRIVILEGES)NULL, 0);
  667. return TRUE;
  668. }
  669. // Shutting down flushes file buffers to disk and brings the system to a condition in which it is safe to turn off the computer
  670. // The application must first enable the SE_SHUTDOWN_NAME privilege.
  671. // The final parameter in the call to ExitWindowsEx indicates that the system was shut down for a planning update of the operating system.
  672. BOOL MySystemShutdown()
  673. {
  674. HANDLE hToken;
  675. TOKEN_PRIVILEGES tkp;
  676. // Get a token for this process.
  677. if (!OpenProcessToken(GetCurrentProcess(),
  678. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  679. return(FALSE);
  680. // Get the LUID for the shutdown privilege.
  681. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
  682. &tkp.Privileges[0].Luid);
  683. tkp.PrivilegeCount = 1; // one privilege to set
  684. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  685. // Get the shutdown privilege for this process.
  686. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
  687. (PTOKEN_PRIVILEGES)NULL, 0);
  688. if (GetLastError() != ERROR_SUCCESS)
  689. return FALSE;
  690. // Shut down the system and force all applications to close.
  691. if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE,
  692. SHTDN_REASON_MAJOR_OPERATINGSYSTEM |
  693. SHTDN_REASON_MINOR_UPGRADE |
  694. SHTDN_REASON_FLAG_PLANNED))
  695. return FALSE;
  696. return TRUE;
  697. }