|
@@ -0,0 +1,1061 @@
|
|
|
+#include "StdAfx.h"
|
|
|
+#include "Global.h"
|
|
|
+
|
|
|
+// 获取文件版本号函数头文件;
|
|
|
+#include <WinVer.h>
|
|
|
+#pragma comment(lib,"version.lib")
|
|
|
+using namespace std;
|
|
|
+#include <psapi.h>
|
|
|
+#pragma comment(lib,"Psapi.lib")
|
|
|
+#include <locale.h>
|
|
|
+#include <io.h>//_access头文件;
|
|
|
+
|
|
|
+namespace GLOBAL
|
|
|
+{
|
|
|
+ CONFIG g_config;
|
|
|
+ TCHAR g_szModulePath[MAX_PATH] = _T(""); // 软件目录;
|
|
|
+ TCHAR g_szModuleFileName[MAX_PATH] = _T(""); // 软件名称;
|
|
|
+ TCHAR g_szConfigFile[MAX_PATH] = _T("");
|
|
|
+ PROC_WND_INFO g_procWndInfo;
|
|
|
+ BOOL g_bHijacted = FALSE;
|
|
|
+#define TRACE4(sz, p1, p2, p3, p4) TRACE(_T(sz), p1, p2, p3, p4)
|
|
|
+
|
|
|
+ BOOL GetConfigInfo(LPCTSTR lpIniDir /* = NULL */, LPCTSTR lpConfigName /* = NULL */)
|
|
|
+ {
|
|
|
+ TCHAR szDrive[_MAX_DRIVE] = { 0 };
|
|
|
+ TCHAR szDir[_MAX_DIR] = { 0 };
|
|
|
+ TCHAR szFna[_MAX_DIR] = { 0 };
|
|
|
+ TCHAR szExt[_MAX_DIR] = { 0 };
|
|
|
+ ::GetModuleFileName(NULL, g_szModulePath, sizeof(g_szModulePath) / sizeof(TCHAR));
|
|
|
+ _stprintf_s(g_szModuleFileName, _T("%s"), g_szModulePath);
|
|
|
+
|
|
|
+ _tsplitpath_s(g_szModulePath, szDrive, szDir, szFna, szExt);
|
|
|
+ _tcscpy_s(g_szModulePath, szDrive);
|
|
|
+ _tcscat_s(g_szModulePath, szDir);
|
|
|
+
|
|
|
+ if (lpIniDir != NULL && lpConfigName != NULL)
|
|
|
+ _stprintf_s(g_szConfigFile, _T("%s%s"), lpIniDir, lpConfigName);
|
|
|
+ else
|
|
|
+ _stprintf_s(g_szConfigFile, _T("%s%s.ini"), g_szModulePath, szFna);
|
|
|
+
|
|
|
+ HANDLE hFile = CreateFile(g_szConfigFile, 0/*GENERIC_READ*/, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
|
+
|
|
|
+ if (ERROR_FILE_NOT_FOUND == GetLastError())
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseHandle(hFile);
|
|
|
+ hFile = NULL;
|
|
|
+
|
|
|
+#pragma region 获取配置文件信息;
|
|
|
+ TCHAR szValue[MAX_PATH] = {0};
|
|
|
+ // LOGIN;
|
|
|
+ GetPrivateProfileString(_T("LOGIN"), _T("account"), _T(""), g_config.szAccount, MAX_PATH, g_szConfigFile);
|
|
|
+ GetPrivateProfileString(_T("LOGIN"), _T("password"), _T(""), g_config.szPassword, MAX_PATH, g_szConfigFile);
|
|
|
+ GetPrivateProfileString(_T("LOGIN"), _T("line"), _T(""), g_config.szLine, MAX_PATH, g_szConfigFile);
|
|
|
+ g_config.nOffline = GetPrivateProfileInt(_T("LOGIN"), _T("offline"), 0, g_szConfigFile);
|
|
|
+ // SYSTEM;
|
|
|
+ g_config.nStdOut = GetPrivateProfileInt(_T("SYSTEM"), _T("stdprint"), 0, g_szConfigFile);
|
|
|
+ GetPrivateProfileString(_T("SYSTEM"), _T("OGCTool"), _T(""), g_config.szOGCToolProgram, MAX_PATH, g_szConfigFile);
|
|
|
+ // BATCH;
|
|
|
+ g_config.nDeltaEType = GetPrivateProfileInt(_T("BATCH"), _T("EType"), 0, g_szConfigFile);
|
|
|
+ GetPrivateProfileString(_T("BATCH"), _T("EValue"), _T(""), szValue, MAX_PATH, g_szConfigFile);
|
|
|
+ g_config.dDeltaEValue = _tstof(szValue);
|
|
|
+ GetPrivateProfileString(_T("BATCH"), _T("batchNumber"), _T(""), g_config.szBatchNumber, MAX_PATH, g_szConfigFile);
|
|
|
+#pragma endregion
|
|
|
+
|
|
|
+ if ( g_config.nStdOut ) {
|
|
|
+ AllocConsole(); // 开辟控制台;
|
|
|
+ SetConsoleTitle(_T("调试输出")); // 设置控制台窗口标题;
|
|
|
+ freopen("CONOUT$", "w+t", stdout); // 重定向输出;
|
|
|
+ freopen("CONIN$", "r+t", stdin); // 重定向输入;
|
|
|
+
|
|
|
+ HWND hWnd = NULL;
|
|
|
+again:
|
|
|
+ hWnd = ::FindWindow(NULL, _T("调试输出"));
|
|
|
+ if( hWnd ) {
|
|
|
+ if (!::SetWindowPos(hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE)) {
|
|
|
+ _tprintf_s(_T("前置设置失败\n"));
|
|
|
+ } else {
|
|
|
+ _tprintf_s(_T("前置设置成功\n"));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ goto again;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ DWORD FindProcess(LPCTSTR lpProName)
|
|
|
+ {
|
|
|
+ ASSERT(lpProName!=NULL);
|
|
|
+
|
|
|
+ DWORD dwProcId = 0;
|
|
|
+ PROCESSENTRY32 pe32 = { 0 };
|
|
|
+
|
|
|
+ HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
+ if (hSnapshot == NULL)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ pe32.dwSize = sizeof(PROCESSENTRY32);
|
|
|
+
|
|
|
+ if (Process32First(hSnapshot, &pe32))
|
|
|
+ {
|
|
|
+ do {
|
|
|
+ if (_tcsicmp(lpProName, pe32.szExeFile) == 0)
|
|
|
+ {
|
|
|
+ dwProcId = pe32.th32ProcessID;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } while (Process32Next(hSnapshot, &pe32));
|
|
|
+ }
|
|
|
+ CloseHandle(hSnapshot);
|
|
|
+
|
|
|
+ return dwProcId;
|
|
|
+ }
|
|
|
+
|
|
|
+ vector<DWORD> FindAllProcess(LPCTSTR lpProName)
|
|
|
+ {
|
|
|
+ ASSERT(lpProName!=NULL);
|
|
|
+
|
|
|
+ vector<DWORD> vtPID;
|
|
|
+ PROCESSENTRY32 pe32 = { 0 };
|
|
|
+
|
|
|
+ HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
+ if (hSnapshot == NULL)
|
|
|
+ return vector<DWORD>();
|
|
|
+
|
|
|
+ pe32.dwSize = sizeof(PROCESSENTRY32);
|
|
|
+ if (Process32First(hSnapshot, &pe32))
|
|
|
+ {
|
|
|
+ do {
|
|
|
+ if (_tcsicmp(lpProName, pe32.szExeFile) == 0)
|
|
|
+ {
|
|
|
+ vtPID.push_back(pe32.th32ProcessID);
|
|
|
+ }
|
|
|
+ } while (Process32Next(hSnapshot, &pe32));
|
|
|
+ }
|
|
|
+ CloseHandle(hSnapshot);
|
|
|
+
|
|
|
+ return vtPID;
|
|
|
+ }
|
|
|
+
|
|
|
+ void FindAllProcess(std::vector<PROC_INFO> &vtProInfo)
|
|
|
+ {
|
|
|
+ PROCESSENTRY32 pe32 = { 0 };
|
|
|
+ HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
+ if (hSnapshot == NULL)
|
|
|
+ return;
|
|
|
+
|
|
|
+ pe32.dwSize = sizeof(PROCESSENTRY32);
|
|
|
+ if (!Process32First(hSnapshot, &pe32))
|
|
|
+ goto end;
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ PROC_INFO proinfo;
|
|
|
+ proinfo.dwProcId = pe32.th32ProcessID;
|
|
|
+ proinfo.strProcName = pe32.szExeFile;
|
|
|
+ vtProInfo.push_back(proinfo);
|
|
|
+ } while (Process32Next(hSnapshot, &pe32));
|
|
|
+
|
|
|
+end:
|
|
|
+ CloseHandle(hSnapshot);
|
|
|
+ }
|
|
|
+
|
|
|
+ HANDLE FindModule(LPCTSTR lpModuleName, DWORD dwProcId)
|
|
|
+ {
|
|
|
+ ASSERT(lpModuleName!=NULL);
|
|
|
+
|
|
|
+ DWORD dwMID = 0;
|
|
|
+ MODULEENTRY32 me32 = { 0 };
|
|
|
+ HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, dwProcId);
|
|
|
+ if (hSnapshot == NULL)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ me32.dwSize = sizeof(MODULEENTRY32);
|
|
|
+ if (Module32First(hSnapshot, &me32))
|
|
|
+ {
|
|
|
+ do {
|
|
|
+ if (_tcsicmp(lpModuleName, me32.szModule) == 0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } while (Module32Next(hSnapshot, &me32));
|
|
|
+ }
|
|
|
+ CloseHandle(hSnapshot);
|
|
|
+
|
|
|
+ return me32.hModule;
|
|
|
+ }
|
|
|
+
|
|
|
+ LPCTSTR GetModulePath(LPCTSTR lpModuleName, DWORD dwProcId)
|
|
|
+ {
|
|
|
+ ASSERT(lpModuleName!=NULL);
|
|
|
+
|
|
|
+ DWORD dwMID = 0;
|
|
|
+ MODULEENTRY32 me32 = { 0 };
|
|
|
+ HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, dwProcId);
|
|
|
+ if (hSnapshot == NULL)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ me32.dwSize = sizeof(MODULEENTRY32);
|
|
|
+ if (Module32First(hSnapshot, &me32))
|
|
|
+ {
|
|
|
+ do {
|
|
|
+ if (_tcsicmp(lpModuleName, me32.szModule) == 0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } while (Module32Next(hSnapshot, &me32));
|
|
|
+ }
|
|
|
+ CloseHandle(hSnapshot);
|
|
|
+
|
|
|
+ return me32.szExePath;
|
|
|
+ }
|
|
|
+
|
|
|
+ HANDLE FindModuleEx(LPCTSTR lpModuleName, DWORD dwProcId)
|
|
|
+ {
|
|
|
+ HMODULE hMods[1024] = {0};
|
|
|
+ DWORD cbNeeded = 0;
|
|
|
+ TCHAR szModName[MAX_PATH];
|
|
|
+ BOOL Wow64Process;
|
|
|
+
|
|
|
+ HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcId);
|
|
|
+ IsWow64Process(hProcess, &Wow64Process); //判断是32位还是64位进程
|
|
|
+ if ( EnumProcessModulesEx(hProcess, hMods, sizeof(hMods), &cbNeeded, Wow64Process?LIST_MODULES_32BIT:LIST_MODULES_64BIT) )
|
|
|
+ {
|
|
|
+ for (UINT i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
|
|
|
+ {
|
|
|
+ GetModuleFileNameEx(hProcess, hMods[i], szModName, _countof(szModName));
|
|
|
+#ifdef _DEBUG
|
|
|
+ WriteTextLog(_T("目标=%s, 原始=%s, 地址=%p"), szModName, lpModuleName, hMods[i]);
|
|
|
+#endif
|
|
|
+ if (_tcsicmp(lpModuleName, szModName) == 0)
|
|
|
+ {
|
|
|
+ CloseHandle(hProcess);
|
|
|
+ WriteTextLog(_T("【目标=%s, 原始=%s, 地址=%p】"), szModName, lpModuleName, hMods[i]);
|
|
|
+ return hMods[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseHandle(hProcess);
|
|
|
+
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ // WINDOWS NT 以上的内核需要提权,才能对系统进行高级管理;
|
|
|
+ BOOL GetDebugPriv()
|
|
|
+ {
|
|
|
+ // 返回的访问令牌指针;
|
|
|
+ HANDLE hToken;
|
|
|
+ // 接收所返回的制定特权名称的信息;
|
|
|
+ LUID sedebugnameValue;
|
|
|
+ // 新特权信息的指针(结构体);
|
|
|
+ TOKEN_PRIVILEGES tkp;
|
|
|
+ //DWORD dwCurProcId = GetCurrentProcessId();
|
|
|
+ // 要修改访问权限的进程句柄;
|
|
|
+ HANDLE hCurProc = ::GetCurrentProcess();
|
|
|
+ //hCurProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwCurProcId);
|
|
|
+
|
|
|
+ if (!::OpenProcessToken(hCurProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
|
|
|
+ {
|
|
|
+ CloseHandle(hToken);
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ tkp.PrivilegeCount = 1;
|
|
|
+ tkp.Privileges[0].Luid = sedebugnameValue;
|
|
|
+ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
+
|
|
|
+ if (!::AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
|
|
|
+ {
|
|
|
+ CloseHandle(hToken);
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseHandle(hCurProc);
|
|
|
+ CloseHandle(hToken);
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /************************************************************************/
|
|
|
+ /*
|
|
|
+ 函数:GetFileVersion
|
|
|
+ 描述:获取可执行文件的文件版号;
|
|
|
+ 参数:
|
|
|
+ hModule[IN] 可执行文件模块句柄;
|
|
|
+ dwArray[OUT] 返回的文件版本号;
|
|
|
+ 返回:
|
|
|
+ 成功返回TRUE,失败返回FALSE;
|
|
|
+ 注意:
|
|
|
+ 当hModule为空时,表示要获取的可执行文件为本程序的文件版本号;
|
|
|
+ */
|
|
|
+ /************************************************************************/
|
|
|
+ BOOL GetFileVersion( IN HMODULE hModule, OUT DWORD (&dwArray)[4])
|
|
|
+ {
|
|
|
+ TCHAR fname[MAX_PATH];
|
|
|
+ VS_FIXEDFILEINFO *pVi;
|
|
|
+ DWORD dwHandle;
|
|
|
+
|
|
|
+ if ( GetModuleFileName(hModule, fname, MAX_PATH))
|
|
|
+ {
|
|
|
+ INT nSize = GetFileVersionInfoSize(fname, &dwHandle);
|
|
|
+
|
|
|
+ if (nSize > 0)
|
|
|
+ {
|
|
|
+ BYTE *pBuffer = new BYTE[nSize];
|
|
|
+ memset(pBuffer, 0, nSize);
|
|
|
+
|
|
|
+ if (GetFileVersionInfo(fname, dwHandle, nSize, pBuffer))
|
|
|
+ {
|
|
|
+ if (VerQueryValue(pBuffer, _T("\\"), (LPVOID *)&pVi, (PUINT)&nSize))
|
|
|
+ {
|
|
|
+ dwArray[0] = HIWORD(pVi->dwFileVersionMS);
|
|
|
+ dwArray[1] = LOWORD(pVi->dwFileVersionMS);
|
|
|
+ dwArray[2] = HIWORD(pVi->dwFileVersionLS);
|
|
|
+ dwArray[3] = LOWORD(pVi->dwFileVersionLS);
|
|
|
+
|
|
|
+ delete[]pBuffer;
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( pBuffer )
|
|
|
+ delete[]pBuffer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /************************************************************************/
|
|
|
+ /*
|
|
|
+ 函数:GetFileVersion
|
|
|
+ 描述:获取可执行文件的文件版号;
|
|
|
+ 参数:
|
|
|
+ lpFileName[IN] 可执行文件名全路径;
|
|
|
+ dwArray[OUT] 返回的文件版本号;
|
|
|
+ 返回:
|
|
|
+ 成功返回TRUE,失败返回FALSE;
|
|
|
+ 注意:
|
|
|
+ */
|
|
|
+ /************************************************************************/
|
|
|
+ BOOL GetFileVersionEx( IN LPCTSTR lpFileName, IN DWORD (&dwArray)[4] )
|
|
|
+ {
|
|
|
+ if ( lpFileName == NULL || !PathFileExists(lpFileName) )
|
|
|
+ {
|
|
|
+ OutputDebugString(_T("文件名错误或文件不存在\n"));
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ DWORD dwHandle = 0;
|
|
|
+ VS_FIXEDFILEINFO *pVi = NULL;
|
|
|
+ INT nSize = GetFileVersionInfoSize(lpFileName, &dwHandle);
|
|
|
+ if ( nSize > 0 )
|
|
|
+ {
|
|
|
+ BYTE *pBuffer = new BYTE[nSize];
|
|
|
+ memset(pBuffer, 0, nSize);
|
|
|
+
|
|
|
+ if ( GetFileVersionInfo(lpFileName, dwHandle, nSize, pBuffer) )
|
|
|
+ {
|
|
|
+ if (VerQueryValue(pBuffer, _T("\\"), (LPVOID *)&pVi, (PUINT)&nSize))
|
|
|
+ {
|
|
|
+ dwArray[0] = HIWORD(pVi->dwFileVersionMS);
|
|
|
+ dwArray[1] = LOWORD(pVi->dwFileVersionMS);
|
|
|
+ dwArray[2] = HIWORD(pVi->dwFileVersionLS);
|
|
|
+ dwArray[3] = LOWORD(pVi->dwFileVersionLS);
|
|
|
+
|
|
|
+ if (pBuffer)
|
|
|
+ delete[]pBuffer;
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pBuffer)
|
|
|
+ delete[]pBuffer;
|
|
|
+ }
|
|
|
+
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /************************************************************************/
|
|
|
+ /*
|
|
|
+ 函数:GetProductVersion
|
|
|
+ 描述:获取可执行文件的产品版号;
|
|
|
+ 参数:
|
|
|
+ hModule[IN] 可执行文件模块句柄;
|
|
|
+ dwArray[OUT] 返回的产品版本号;
|
|
|
+ 返回:
|
|
|
+ 成功返回TRUE,失败返回FALSE;
|
|
|
+ 注意:
|
|
|
+ 当hModule为空时,表示要获取的可执行文件为本程序的产品版本号;
|
|
|
+ */
|
|
|
+ /************************************************************************/
|
|
|
+ BOOL GetProductVersion(IN HMODULE hModule, IN DWORD (&dwArray)[4] )
|
|
|
+ {
|
|
|
+ TCHAR fname[MAX_PATH];
|
|
|
+ VS_FIXEDFILEINFO *pVi;
|
|
|
+ DWORD dwHandle;
|
|
|
+
|
|
|
+ if (::GetModuleFileName(hModule, fname, MAX_PATH))
|
|
|
+ {
|
|
|
+ INT nSize = GetFileVersionInfoSize(fname, &dwHandle);
|
|
|
+
|
|
|
+ if (nSize > 0)
|
|
|
+ {
|
|
|
+ BYTE *pBuffer = new BYTE[nSize];
|
|
|
+ memset(pBuffer, 0, nSize);
|
|
|
+
|
|
|
+ if (GetFileVersionInfo(fname, dwHandle, nSize, pBuffer))
|
|
|
+ {
|
|
|
+ if (VerQueryValue(pBuffer, _T("\\"), (LPVOID *)&pVi, (PUINT)&nSize))
|
|
|
+ {
|
|
|
+ dwArray[0] = HIWORD(pVi->dwProductVersionMS);
|
|
|
+ dwArray[1] = LOWORD(pVi->dwProductVersionMS);
|
|
|
+ dwArray[2] = HIWORD(pVi->dwProductVersionLS);
|
|
|
+ dwArray[3] = LOWORD(pVi->dwProductVersionLS);
|
|
|
+
|
|
|
+ if(pBuffer)
|
|
|
+ delete[]pBuffer;
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(pBuffer)
|
|
|
+ delete[]pBuffer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /************************************************************************/
|
|
|
+ /*
|
|
|
+ 函数:GetProductVersion
|
|
|
+ 描述:获取可执行文件的产品版号;
|
|
|
+ 参数:
|
|
|
+ lpFileName[IN] 可执行文件名全路径;
|
|
|
+ dwArray[OUT] 返回的产品版本号;
|
|
|
+ 返回:
|
|
|
+ 成功返回TRUE,失败返回FALSE;
|
|
|
+ 注意:
|
|
|
+ */
|
|
|
+ /************************************************************************/
|
|
|
+ BOOL GetProductVersionEx( IN LPCTSTR lpFileName, IN DWORD (&dwArray)[4] )
|
|
|
+ {
|
|
|
+ if ( lpFileName == NULL || !PathFileExists(lpFileName) )
|
|
|
+ {
|
|
|
+ OutputDebugString(_T("文件名错误或文件不存在\n"));
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ DWORD dwHandle = 0;
|
|
|
+ VS_FIXEDFILEINFO *pVi = NULL;
|
|
|
+ INT nSize = GetFileVersionInfoSize(lpFileName, &dwHandle);
|
|
|
+ if ( nSize > 0 )
|
|
|
+ {
|
|
|
+ BYTE *pBuffer = new BYTE[nSize];
|
|
|
+ memset(pBuffer, 0, nSize);
|
|
|
+
|
|
|
+ if ( GetFileVersionInfo(lpFileName, dwHandle, nSize, pBuffer) )
|
|
|
+ {
|
|
|
+ if (VerQueryValue(pBuffer, _T("\\"), (LPVOID *)&pVi, (PUINT)&nSize))
|
|
|
+ {
|
|
|
+ dwArray[0] = HIWORD(pVi->dwProductVersionMS);
|
|
|
+ dwArray[1] = LOWORD(pVi->dwProductVersionMS);
|
|
|
+ dwArray[2] = HIWORD(pVi->dwProductVersionLS);
|
|
|
+ dwArray[3] = LOWORD(pVi->dwProductVersionLS);
|
|
|
+
|
|
|
+ if (pBuffer)
|
|
|
+ delete[]pBuffer;
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pBuffer)
|
|
|
+ delete[]pBuffer;
|
|
|
+ }
|
|
|
+
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /************************************************************************/
|
|
|
+ /* 函数:WriteTextLog[7/28/2016 IT];
|
|
|
+ /* 描述:写文本日志;
|
|
|
+ /* 参数:;
|
|
|
+ /* [IN] :;
|
|
|
+ /* 返回:void;
|
|
|
+ /* 注意:;
|
|
|
+ /* 示例:;
|
|
|
+ /*
|
|
|
+ /* 修改:;
|
|
|
+ /* 日期:;
|
|
|
+ /* 内容:;
|
|
|
+ /************************************************************************/
|
|
|
+ void WriteTextLog(const TCHAR *format, ...)
|
|
|
+ {
|
|
|
+#if 0
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //static ThreadSection _critSection;
|
|
|
+ //AutoThreadSection aSection(&_critSection);
|
|
|
+ // 解析出日志路径;
|
|
|
+ TCHAR szlogpath[MAX_PATH] = {0};
|
|
|
+ static TCHAR szModulePath[MAX_PATH] = {0};
|
|
|
+ static TCHAR szFna[_MAX_DIR] = { 0 };
|
|
|
+ if ( szModulePath[0] == _T('\0') )
|
|
|
+ {
|
|
|
+ TCHAR szDrive[_MAX_DRIVE] = { 0 };
|
|
|
+ TCHAR szDir[_MAX_DIR] = { 0 };
|
|
|
+ TCHAR szExt[_MAX_DIR] = { 0 };
|
|
|
+ ::GetModuleFileName(NULL, szModulePath, sizeof(szModulePath) / sizeof(TCHAR));
|
|
|
+ _tsplitpath_s(szModulePath, szDrive, szDir, szFna, szExt);
|
|
|
+ _tcscpy_s(szModulePath, szDrive);
|
|
|
+ _tcscat_s(szModulePath, szDir);
|
|
|
+ }
|
|
|
+
|
|
|
+ _stprintf_s(szlogpath, _T("%s日志\\%s%s.txt"), szModulePath, szFna, CTime::GetCurrentTime().Format("[%Y-%m-%d]"));
|
|
|
+
|
|
|
+ // 打开或创建文件;
|
|
|
+ CStdioFile fp;
|
|
|
+ if (PathFileExists(szlogpath))
|
|
|
+ {
|
|
|
+ if (fp.Open(szlogpath, CFile::modeWrite) == FALSE)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ fp.SeekToEnd();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fp.Open(szlogpath, CFile::modeCreate | CFile::modeWrite);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 格式化前设置语言区域;
|
|
|
+ TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
|
|
|
+ _tsetlocale(LC_CTYPE, _T("chs"));//设定中文;
|
|
|
+
|
|
|
+ // 格式化日志内容;
|
|
|
+ va_list args = NULL;
|
|
|
+ int len = 0;
|
|
|
+ TCHAR *buffer = NULL;
|
|
|
+ va_start( args, format );
|
|
|
+ // _vscprintf doesn't count. terminating '\0'
|
|
|
+ len = _vsctprintf( format, args ) + 1;
|
|
|
+ buffer = (TCHAR*)malloc( len * sizeof(TCHAR) );
|
|
|
+ _vstprintf_s( buffer, len, format, args ); // C4996
|
|
|
+ // Note: vsprintf is deprecated; consider using vsprintf_s instead
|
|
|
+
|
|
|
+ // 将日志内容输入到文件中;
|
|
|
+ fp.WriteString( CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S ")) );
|
|
|
+ fp.WriteString(buffer);
|
|
|
+ fp.WriteString(_T("\n"));
|
|
|
+
|
|
|
+ // 关闭文件,释放资源并设置回原语言区域;
|
|
|
+ free( buffer );
|
|
|
+ _tsetlocale(LC_CTYPE, old_locale);
|
|
|
+ free(old_locale);//还原区域设定;
|
|
|
+ fp.Close();
|
|
|
+ }
|
|
|
+ catch (CException *e)
|
|
|
+ {
|
|
|
+ e->ReportError();
|
|
|
+ e->Delete();
|
|
|
+ }
|
|
|
+#else
|
|
|
+ // 解析出日志路径;
|
|
|
+ TCHAR szlogpath[MAX_PATH] = { 0 };
|
|
|
+ static TCHAR szModulePath[MAX_PATH] = { 0 };
|
|
|
+ static TCHAR szFna[MAX_PATH] = { 0 };
|
|
|
+ if (szModulePath[0] == _T('\0'))
|
|
|
+ {
|
|
|
+ TCHAR szDrive[MAX_PATH] = { 0 };
|
|
|
+ TCHAR szDir[MAX_PATH] = { 0 };
|
|
|
+ TCHAR szExt[MAX_PATH] = { 0 };
|
|
|
+ ::GetModuleFileName(NULL, szModulePath, sizeof(szModulePath) / sizeof(TCHAR));
|
|
|
+ _tsplitpath_s(szModulePath, szDrive, szDir, szFna, szExt);
|
|
|
+ _tcscpy_s(szModulePath, szDrive);
|
|
|
+ _tcscat_s(szModulePath, szDir);
|
|
|
+ }
|
|
|
+
|
|
|
+ _stprintf_s(szlogpath, _T("%s%s.txt"), szModulePath, szFna);
|
|
|
+ // 打开或创建文件;
|
|
|
+ FILE *fp = NULL;
|
|
|
+ //if (_taccess(szlogpath, 0) != -1)
|
|
|
+#ifndef UNICODE
|
|
|
+ if (_access(szlogpath, 0) != -1)
|
|
|
+#else
|
|
|
+ if (_taccess(szlogpath, 0) != -1)
|
|
|
+#endif
|
|
|
+ {// 存在;
|
|
|
+ fp = _tfopen(szlogpath, _T("a+"));
|
|
|
+ // 移动到末尾;
|
|
|
+ fseek(fp, 0, SEEK_END);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {// 不存在;
|
|
|
+ fp = _tfopen(szlogpath, _T("w+"));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fp == NULL)
|
|
|
+ return;
|
|
|
+
|
|
|
+ // 格式化前设置语言区域;
|
|
|
+ TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
|
|
|
+ _tsetlocale(LC_CTYPE, _T("chs"));//设定中文;
|
|
|
+
|
|
|
+ // 格式化日志内容;
|
|
|
+ va_list args = NULL;
|
|
|
+ int len = 0;
|
|
|
+ TCHAR *buffer = NULL;
|
|
|
+ va_start(args, format);
|
|
|
+ // _vscprintf doesn't count. terminating '\0'
|
|
|
+ len = _vsctprintf(format, args) + 1;
|
|
|
+ buffer = (TCHAR*)malloc(len * sizeof(TCHAR));
|
|
|
+ _vstprintf_s(buffer, len, format, args);
|
|
|
+ // 将日志内容输入到文件中;
|
|
|
+ // 获取今年年份;
|
|
|
+ __time64_t gmt = time(NULL);// 获取当前日历时间(1900-01-01开始的Unix时间戳);
|
|
|
+ struct tm gmtm = { 0 };
|
|
|
+ localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
|
|
|
+ _ftprintf(fp, _T("%04d-%02d-%02d %02d:%02d:%02d %s\n"), gmtm.tm_year + 1990, gmtm.tm_mon + 1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec, buffer);
|
|
|
+
|
|
|
+ // 关闭文件,释放资源并设置回原语言区域;
|
|
|
+ free(buffer);
|
|
|
+ fclose(fp);
|
|
|
+ _tsetlocale(LC_CTYPE, old_locale);
|
|
|
+ free(old_locale);//还原区域设定;
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //---------------------------------------------------------------------
|
|
|
+ // add by Jeff 2014.10.27
|
|
|
+ // 函数:全局函数IsDirectoryLegitimate,多字节版本,非UNICODE
|
|
|
+ // 描述:判断一个目录路径字符串,是否属于合法的、可创建的目录路径。
|
|
|
+ // 参数:strDirectory 被验证的路径字符串;
|
|
|
+ //
|
|
|
+ // 返回:合法路径返回TRUE;
|
|
|
+ //---------------------------------------------------------------------
|
|
|
+ BOOL IsDirectoryLegitimate(const CString &strDirectory)
|
|
|
+ {
|
|
|
+ if (strDirectory.Find('/') != -1 ||
|
|
|
+ strDirectory.Find('\\') != -1 ||
|
|
|
+ strDirectory.Find(':') != -1 ||
|
|
|
+ strDirectory.Find('*') != -1 ||
|
|
|
+ strDirectory.Find('?') != -1 ||
|
|
|
+ strDirectory.Find('\"') != -1 ||
|
|
|
+ strDirectory.Find('>') != -1 ||
|
|
|
+ strDirectory.Find('<') != -1 ||
|
|
|
+ strDirectory.Find('|') != -1
|
|
|
+ )
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //--------------------------------------------------------------------------------
|
|
|
+ // Jeff add 2014.06.23;
|
|
|
+ // 函数:ErrorExit
|
|
|
+ // 描述:
|
|
|
+ // 参数:
|
|
|
+ // lpszFunction:函数名;
|
|
|
+ // dwError:错误码;
|
|
|
+ //
|
|
|
+ //--------------------------------------------------------------------------------
|
|
|
+ void ShowSystemErrorInfo(CString strDescription, const DWORD &dwError)
|
|
|
+ {
|
|
|
+#if 1
|
|
|
+ LPVOID lpMsgBuf;
|
|
|
+
|
|
|
+ BOOL fOk = FormatMessage(
|
|
|
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
|
+ FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
+ FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
+ NULL,
|
|
|
+ dwError,
|
|
|
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
|
+ (LPTSTR)&lpMsgBuf,
|
|
|
+ 0, NULL);
|
|
|
+
|
|
|
+ if (!fOk)
|
|
|
+ {
|
|
|
+ // Is it a network-related error?
|
|
|
+ HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);
|
|
|
+
|
|
|
+ if (hDll != NULL)
|
|
|
+ {
|
|
|
+ FormatMessage(
|
|
|
+ FORMAT_MESSAGE_FROM_HMODULE |
|
|
|
+ FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
+ FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
+ hDll,
|
|
|
+ dwError,
|
|
|
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
|
|
+ (LPTSTR)&lpMsgBuf,
|
|
|
+ 0,
|
|
|
+ NULL);
|
|
|
+
|
|
|
+ FreeLibrary(hDll);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (lpMsgBuf != NULL)
|
|
|
+ {
|
|
|
+ CString strDisplay;
|
|
|
+ strDisplay.Format(_T("%s.错误码=%d,Windows描述:%s"), strDescription, dwError, (PCTSTR)LocalLock(lpMsgBuf));
|
|
|
+ //WriteLog(strDisplay);
|
|
|
+ LocalFree(lpMsgBuf);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //WriteLog(strDescription);
|
|
|
+ }
|
|
|
+#else
|
|
|
+ HLOCAL hlocal = NULL; // Buffer that gets the error message string
|
|
|
+
|
|
|
+ // Get the error code's textual description
|
|
|
+ BOOL fOk = FormatMessage(
|
|
|
+ FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
|
+ FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
+ NULL,
|
|
|
+ dwError,
|
|
|
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
|
|
+ (PTSTR)&hlocal,
|
|
|
+ 0,
|
|
|
+ NULL);
|
|
|
+
|
|
|
+ if (!fOk)
|
|
|
+ {
|
|
|
+ // Is it a network-related error?
|
|
|
+ HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);
|
|
|
+
|
|
|
+ if (hDll != NULL)
|
|
|
+ {
|
|
|
+ FormatMessage(
|
|
|
+ FORMAT_MESSAGE_FROM_HMODULE |
|
|
|
+ FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
+ FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
+ hDll,
|
|
|
+ dwError,
|
|
|
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
|
|
+ (PTSTR)&hlocal,
|
|
|
+ 0,
|
|
|
+ NULL);
|
|
|
+ FreeLibrary(hDll);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hlocal != NULL)
|
|
|
+ {
|
|
|
+ CString strDisplay;
|
|
|
+ strDisplay.Format("%s 失败错误码=%d,Windows系统描述:%s", strDescription, dwError, (PCTSTR)LocalLock(hlocal));
|
|
|
+ //WriteLog(strDisplay);
|
|
|
+ LocalFree(hlocal);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //WriteLog("Error number not found.");
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 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).
|
|
|
+ // After the time-out interval elapses, the system is restarted.
|
|
|
+ //The application must enable the SE_SHUTDOWN_NAME privilege before calling InitiateSystemShutdown
|
|
|
+ BOOL MySystemShutdown(LPTSTR lpMsg)
|
|
|
+ {
|
|
|
+ HANDLE hToken; // handle to process token
|
|
|
+ TOKEN_PRIVILEGES tkp; // pointer to token structure
|
|
|
+
|
|
|
+ BOOL fResult; // system shutdown flag
|
|
|
+
|
|
|
+ // Get the current process token handle so we can get shutdown
|
|
|
+ // privilege.
|
|
|
+
|
|
|
+ if (!OpenProcessToken(GetCurrentProcess(),
|
|
|
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ // Get the LUID for shutdown privilege.
|
|
|
+
|
|
|
+ LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
|
|
|
+ &tkp.Privileges[0].Luid);
|
|
|
+
|
|
|
+ tkp.PrivilegeCount = 1; // one privilege to set
|
|
|
+ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
+
|
|
|
+ // Get shutdown privilege for this process.
|
|
|
+
|
|
|
+ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
|
|
|
+ (PTOKEN_PRIVILEGES)NULL, 0);
|
|
|
+
|
|
|
+ // Cannot test the return value of AdjustTokenPrivileges.
|
|
|
+
|
|
|
+ if (GetLastError() != ERROR_SUCCESS)
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ // Display the shutdown dialog box and start the countdown.
|
|
|
+
|
|
|
+ fResult = InitiateSystemShutdown(
|
|
|
+ NULL, // shut down local computer
|
|
|
+ lpMsg, // message for user
|
|
|
+ 30, // time-out period, in seconds
|
|
|
+ FALSE, // ask user to close apps
|
|
|
+ TRUE); // reboot after shutdown
|
|
|
+
|
|
|
+ if (!fResult)
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ // Disable shutdown privilege.
|
|
|
+
|
|
|
+ tkp.Privileges[0].Attributes = 0;
|
|
|
+ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
|
|
|
+ (PTOKEN_PRIVILEGES)NULL, 0);
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // If the AbortSystemShutdown function is executed in the time-out period specified by InitiateSystemShutdown,
|
|
|
+ // the system does not shut down. For example, if PreventSystemShutdown is called after MySystemShutdown,
|
|
|
+ // the system closes the dialog box and does not restart the system.
|
|
|
+ BOOL PreventSystemShutdown()
|
|
|
+ {
|
|
|
+ HANDLE hToken; // handle to process token
|
|
|
+ TOKEN_PRIVILEGES tkp; // pointer to token structure
|
|
|
+
|
|
|
+ // Get the current process token handle so we can get shutdown
|
|
|
+ // privilege.
|
|
|
+
|
|
|
+ if (!OpenProcessToken(GetCurrentProcess(),
|
|
|
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ // Get the LUID for shutdown privilege.
|
|
|
+
|
|
|
+ LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
|
|
|
+ &tkp.Privileges[0].Luid);
|
|
|
+
|
|
|
+ tkp.PrivilegeCount = 1; // one privilege to set
|
|
|
+ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
+
|
|
|
+ // Get shutdown privilege for this process.
|
|
|
+
|
|
|
+ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
|
|
|
+ (PTOKEN_PRIVILEGES)NULL, 0);
|
|
|
+
|
|
|
+ if (GetLastError() != ERROR_SUCCESS)
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ // Prevent the system from shutting down.
|
|
|
+
|
|
|
+ if (!AbortSystemShutdown(NULL))
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ // Disable shutdown privilege.
|
|
|
+
|
|
|
+ tkp.Privileges[0].Attributes = 0;
|
|
|
+ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
|
|
|
+ (PTOKEN_PRIVILEGES)NULL, 0);
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Shutting down flushes file buffers to disk and brings the system to a condition in which it is safe to turn off the computer
|
|
|
+ // The application must first enable the SE_SHUTDOWN_NAME privilege.
|
|
|
+ // The final parameter in the call to ExitWindowsEx indicates that the system was shut down for a planning update of the operating system.
|
|
|
+ BOOL MySystemShutdown()
|
|
|
+ {
|
|
|
+ HANDLE hToken;
|
|
|
+ TOKEN_PRIVILEGES tkp;
|
|
|
+
|
|
|
+ // Get a token for this process.
|
|
|
+
|
|
|
+ if (!OpenProcessToken(GetCurrentProcess(),
|
|
|
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
|
|
|
+ return(FALSE);
|
|
|
+
|
|
|
+ // Get the LUID for the shutdown privilege.
|
|
|
+
|
|
|
+ LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
|
|
|
+ &tkp.Privileges[0].Luid);
|
|
|
+
|
|
|
+ tkp.PrivilegeCount = 1; // one privilege to set
|
|
|
+ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
+
|
|
|
+ // Get the shutdown privilege for this process.
|
|
|
+
|
|
|
+ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
|
|
|
+ (PTOKEN_PRIVILEGES)NULL, 0);
|
|
|
+
|
|
|
+ if (GetLastError() != ERROR_SUCCESS)
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ // Shut down the system and force all applications to close.
|
|
|
+
|
|
|
+ if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE,
|
|
|
+ SHTDN_REASON_MAJOR_OPERATINGSYSTEM |
|
|
|
+ SHTDN_REASON_MINOR_UPGRADE |
|
|
|
+ SHTDN_REASON_FLAG_PLANNED))
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ HWND GetProcessMainWnd(const DWORD& dwTagetProcessId, LPCTSTR lpTagetWndName)
|
|
|
+ {
|
|
|
+ DWORD dwCurPorcessId = 0;
|
|
|
+ HWND hTagetProcessWnd = NULL;
|
|
|
+ TCHAR szWndName[MAX_PATH] = { 0 };
|
|
|
+ TCHAR szClassName[MAX_PATH] = { 0 };
|
|
|
+
|
|
|
+ // 取得第一个窗口句柄;
|
|
|
+ for (HWND hCurWnd = ::GetTopWindow(NULL); hCurWnd != NULL; hCurWnd = ::GetNextWindow(hCurWnd, GW_HWNDNEXT)) {
|
|
|
+ // 重置为0;
|
|
|
+ dwCurPorcessId = 0;
|
|
|
+ // 通过窗口句柄反查进程pid;
|
|
|
+ DWORD dwThreadId = ::GetWindowThreadProcessId(hCurWnd, &dwCurPorcessId);
|
|
|
+ if (dwThreadId != 0) {
|
|
|
+ // 判断当前进程id是否和目标进程id相同;
|
|
|
+ if (dwCurPorcessId == dwTagetProcessId) {
|
|
|
+ if (lpTagetWndName == NULL) {
|
|
|
+ hTagetProcessWnd = hCurWnd;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // 获取窗口名称;
|
|
|
+ ::GetWindowText(hCurWnd, szWndName, sizeof(szWndName) / sizeof(TCHAR));
|
|
|
+ // 获取窗口类名;
|
|
|
+ ::GetClassName(hCurWnd, szClassName, sizeof(szClassName) / sizeof(TCHAR));
|
|
|
+#ifdef _DEBUG
|
|
|
+ TCHAR szLogMsg[MAX_PATH] = { 0 };
|
|
|
+ _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,窗口地址:%p \n"), szClassName, szWndName, hCurWnd);
|
|
|
+ OutputDebugString(szLogMsg);
|
|
|
+#endif
|
|
|
+ if (_tcsstr(szWndName, lpTagetWndName) != NULL) {
|
|
|
+ hTagetProcessWnd = hCurWnd;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 当前窗口有可能不是进程父窗口;
|
|
|
+ HWND hParentWnd = hTagetProcessWnd;
|
|
|
+ while (hParentWnd) {
|
|
|
+ hParentWnd = ::GetParent(hTagetProcessWnd);
|
|
|
+ if (hParentWnd == NULL)
|
|
|
+ break;
|
|
|
+ hTagetProcessWnd = hParentWnd;
|
|
|
+ }
|
|
|
+
|
|
|
+ return hTagetProcessWnd;
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL CALLBACK EnumChildWindowCallBack(HWND hWnd, LPARAM lParam)
|
|
|
+ {
|
|
|
+ DWORD dwPid = 0;
|
|
|
+ LPPROC_WND_INFO lpWndData = (LPPROC_WND_INFO)lParam;
|
|
|
+ GetWindowThreadProcessId(hWnd, &dwPid); // 获得找到窗口所属的进程
|
|
|
+ if(dwPid == lpWndData->dwProcId) // 判断是否是目标进程的窗口
|
|
|
+ {
|
|
|
+ WND_INFO wndInfo;
|
|
|
+ wndInfo.hWnd=hWnd;
|
|
|
+ SendMessage(hWnd, WM_GETTEXT, MAX_PATH, (LPARAM)wndInfo.szWndTitle);
|
|
|
+ GetClassName(hWnd, wndInfo.szClassName, MAX_PATH);
|
|
|
+ wndInfo.dwCtrlId = ::GetDlgCtrlID(hWnd);
|
|
|
+ lpWndData->AddWnd(wndInfo);
|
|
|
+ // 输出窗口信息
|
|
|
+ TRACE4("A-0x%08X, %ld, %s, %s\n", hWnd, wndInfo.dwCtrlId, wndInfo.szClassName, wndInfo.szWndTitle);
|
|
|
+ // 此处如果再递归,会导致重复查找2次子窗口;
|
|
|
+ //EnumChildWindows(hWnd, EnumChildWindowCallBack, lParam); // 递归查找子窗口
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL CALLBACK EnumWindowCallBack(HWND hWnd, LPARAM lParam)
|
|
|
+ {
|
|
|
+ DWORD dwPid = 0;
|
|
|
+ LPPROC_WND_INFO lpWndData = (LPPROC_WND_INFO)lParam;
|
|
|
+ GetWindowThreadProcessId(hWnd, &dwPid); // 获得找到窗口所属的进程
|
|
|
+ if(dwPid == lpWndData->dwProcId) // 判断是否是目标进程的窗口
|
|
|
+ {
|
|
|
+ WND_INFO wndInfo;
|
|
|
+ wndInfo.hWnd=hWnd;
|
|
|
+ SendMessage(hWnd, WM_GETTEXT, MAX_PATH, (LPARAM)wndInfo.szWndTitle);
|
|
|
+ GetClassName(hWnd, wndInfo.szClassName, MAX_PATH);
|
|
|
+ wndInfo.dwCtrlId = ::GetDlgCtrlID(hWnd);
|
|
|
+ lpWndData->AddWnd(wndInfo);
|
|
|
+ // 输出窗口信息
|
|
|
+ TRACE4("A-0x%08X, %ld, %s, %s\n", hWnd, wndInfo.dwCtrlId, wndInfo.szClassName, wndInfo.szWndTitle);
|
|
|
+ EnumChildWindows(hWnd, EnumChildWindowCallBack, lParam); // 继续查找子窗口
|
|
|
+ }
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL EnumProcessAllWnd(LPPROC_WND_INFO lpProcWndInfo)
|
|
|
+ {
|
|
|
+ return EnumWindows(EnumWindowCallBack, (LPARAM)lpProcWndInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL StartProcess(LPCTSTR lpPath, BOOL bShowWnd, BOOL bSuspend)
|
|
|
+ {
|
|
|
+ STARTUPINFO si;
|
|
|
+ PROCESS_INFORMATION pi;
|
|
|
+ ZeroMemory(&si, sizeof(si));
|
|
|
+ si.cb = sizeof(si);
|
|
|
+ ZeroMemory(&pi, sizeof(pi));
|
|
|
+
|
|
|
+ CString strDir = lpPath;
|
|
|
+ strDir = strDir.Left(strDir.ReverseFind(_T('\\')));
|
|
|
+ si.dwFlags = STARTF_USESHOWWINDOW; // 指定wShowWindow成员有效
|
|
|
+ si.wShowWindow = bShowWnd ? SW_SHOW : SW_HIDE; // 设置创建进程时,窗口不显示,
|
|
|
+ // 为FALSE的话则不显示
|
|
|
+ BOOL bRet = ::CreateProcess (
|
|
|
+ lpPath, // 不在此指定可执行文件的文件名
|
|
|
+ NULL, // 命令行参数
|
|
|
+ NULL, // 默认进程安全性
|
|
|
+ NULL, // 默认线程安全性
|
|
|
+ FALSE, // 指定当前进程内的句柄不可以被子进程继承
|
|
|
+ bSuspend ? CREATE_SUSPENDED : NULL,
|
|
|
+ NULL, // 使用本进程的环境变量
|
|
|
+ strDir, // 使用本进程的驱动器和目录
|
|
|
+ &si,
|
|
|
+ &pi);
|
|
|
+
|
|
|
+ if(bRet)
|
|
|
+ {
|
|
|
+ // 进程挂起后,仍能成功注入dll;
|
|
|
+ // TCHAR szDllPath[MAX_PATH];
|
|
|
+ // ZeroMemory(szDllPath,MAX_PATH);
|
|
|
+ // _stprintf_s(szDllPath, _T("%shook.dll"), g_szModulePath);
|
|
|
+ // for (int i = 0; i < 10; i++)
|
|
|
+ // {
|
|
|
+ // CInjection inject(pi.dwProcessId,szDllPath);
|
|
|
+ // inject.InjectDynamicLibrary();
|
|
|
+ // inject.EjectDynamicLibrary();
|
|
|
+ // }
|
|
|
+ g_procWndInfo.dwProcId = pi.dwProcessId;
|
|
|
+ // 既然我们不使用两个句柄,最好是立刻将它们关闭
|
|
|
+ ::CloseHandle (pi.hThread);
|
|
|
+ ::CloseHandle (pi.hProcess);
|
|
|
+ }
|
|
|
+
|
|
|
+ return bRet;
|
|
|
+ }
|
|
|
+};
|