(1)winmain函數的參數解析:
/* 對于64位應用程序的處理,64位的SR進程只負責將64位dll注入到64位應用程序中,其他工作都由32位SR進程處理 */ LPWSTR *szArgList; int argCount; szArgList = CommandLineToArgvW(GetCommandLine(), &argCount); if (argCount != 2){ g_log.SR_PRintf("SR argument is wrong (%d)", argCount); return -1; } HWND hWnd = (HWND)_ttol(szArgList[0]); if (!IsWindow(hWnd)){ g_log.SR_printf("Hwnd is invalid in 64 bits sr"); return -1; } HANDLE hEvent = (HANDLE)_ttol(szArgList[1]);(2)向某個線程的消息隊列發送消息:需要在線程中創建消息隊列才能使用PostThreadMessage發送消息。LRESULT WINAPI DoExchangeThread(LPVOID lp){ MSG msg; PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);/* force the system to create the message queue */ while (GetMessage(&msg, 0, 0, 0)) { switch (msg.message) { case WM_QUIT_THREAD:/* 通知線程退出 */ g_app_manager.ClearInfo(); return 0; case WM_VM_RECOVER: g_app_manager.ReSendInfo(); break; case WM_VM_RESET: g_app_manager.m_qxl.ResetVersion(); break; case WM_HANDLE_SR: DoSrMessage(msg.wParam, msg.lParam); delete[] (BYTE *)msg.lParam; break; } } return 0;}(3)使用WaitForMultipleObjects監控一組進程的退出消息
LRESULT WINAPI ProcessMoniThread(LPVOID lp){ CAppManager *pManager = (CAppManager *)lp; while (!pManager->m_bStop){ size_t size = pManager->m_appSet.size(); HANDLE *handles = new HANDLE[size + 1]; if (handles == NULL){ g_log.SR_printf("New handles failed error=%d", GetLastError()); break; } DWord *ids = new DWORD[size + 1]; if (ids == NULL){ g_log.SR_printf("New ids failed error=%d", GetLastError()); delete[] handles; break; } int nIndex = 1; handles[0] = pManager->m_hNotice; ids[0] = 0; for (auto item : pManager->m_appSet){ DWORD dwProcessId = item->GetProcessId(); HANDLE hProcess = item->GetProcess(); if (hProcess == nullptr){ pManager->Remove(dwProcessId); } else{ handles[nIndex] = hProcess; ids[nIndex] = dwProcessId; nIndex++; } } DWORD dwRet = WaitForMultipleObjects(nIndex, handles, FALSE, INFINITE);/* 等待有事件激活 */ int nStatus = dwRet - WAIT_OBJECT_0; if (nStatus > 0){/* 有進程退出 */ pManager->Remove(ids[nStatus]); } delete[] handles; delete[] ids; if (nStatus < 0){ g_log.SR_printf("Wait process exit failed error=%d", GetLastError()); break; } } return TRUE;}(4)內存映射文件的使用bool CSRParser::MakeConfDataShared(){ size_t nItemCount = m_mapAttr.size();/* 需要增加全局配置 */ DWORD dwSize = sizeof(SRSharedConfData) + nItemCount*sizeof(SRConData); m_hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, dwSize, SR_FILE_MAP_NAME); if (m_hMapFile == nullptr){ g_log.SR_printf("File map failed error=%d", GetLastError()); return false; } if (GetLastError() == ERROR_ALREADY_EXISTS){ g_log.SR_printf("File map already exists."); CloseHandle(m_hMapFile); m_hMapFile = nullptr; return false; } m_sharedData = (SRSharedConfData *)MapViewOfFile(m_hMapFile, FILE_MAP_ALL_access, 0, 0, 0); if (m_sharedData == nullptr){ g_log.SR_printf("MapViewOfFile failed error=%d", GetLastError()); CloseHandle(m_hMapFile); m_hMapFile = nullptr; return false; } m_sharedData->nCount = (DWORD)nItemCount; int nIndex = 0; for (auto &item : m_mapAttr){ strcpy_s(m_sharedData->buff[nIndex].szName, item.first.c_str()); m_sharedData->buff[nIndex].attr = item.second; nIndex++; } return true;}(5)子進程繼承父進程的內核對象SECURITY_ATTRIBUTES sa;sa.nLength = sizeof(sa);sa.lpSecurityDescriptor = NULL;sa.bInheritHandle = TRUE;/* 需要繼承,這樣子進程可以訪問共享該句柄 */m_hChild = CreateEvent(&sa, FALSE, FALSE, NULL);if (m_hChild == NULL){ g_log.SR_printf("Create child event failed error=%d", GetLastError() );}void CAppManager::StartSR64(HWND hWnd){ if (m_hChild == NULL){ g_log.SR_printf("Start 64 sr failed,m_hChild is NULL."); return; } STARTUPINFO si; PROCESS_INFORMATION pi; TCHAR szCommandLine[64]; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); swprintf_s(szCommandLine, _T("%ld %ld"), hWnd, m_hChild); TCHAR szPath[MAX_PATH]; GetModuleFileName(NULL, szPath, sizeof(szPath)); TCHAR *p = _tcsrchr(szPath, _T('//')); if (p != NULL){ *p = _T('/0'); } _tcscat_s(szPath, _T("//SR64.exe")); if (!CreateProcess(szPath, szCommandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)){ g_log.SR_printf("Create child process failed.(%d)", GetLastError()); } CloseHandle(pi.hThread); CloseHandle(pi.hProcess);}(6)在沒有權限的情況下通過進程句柄查詢進程信息BOOL IsSRProcess(HANDLE hProcess){ char szFileName[MAX_PATH]; HANDLE hProcessAccAdj; /* 因為hProcess沒有查詢權限,如果直接調用查詢的函數會返回失敗,所以需要復制一個句柄并給予查詢權限 */ BOOL bRes = DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcessAccAdj, PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OperaTION | PROCESS_VM_WRITE, FALSE, 0); if (!bRes || hProcessAccAdj == NULL){ UINT unError = GetLastError(); return 0xffffffff; } GetProcessImageFileNameA(hProcessAccAdj, szFileName, sizeof(szFileName)); const char *p = strrchr(szFileName, '//'); if (p != NULL){ return _stricmp("SR64.exe", p + 1) == 0 || _stricmp("SR.exe", p + 1) == 0; } else{ return _stricmp("SR.exe", szFileName) == 0 || _stricmp("SR64.exe", szFileName) == 0; } /* win Vista以上系統可使用 QueryFullProcessImageName */}(6)可等待計時器對象的使用bool CMouseController::SetWheelTimer(){ LARGE_INTEGER liDueTime; HANDLE handle = m_handles[STATUS_WHEEL_TIME_TO_SEND]; liDueTime.QuadPart = -10000 * m_scrollTimeval;//SEDN_WHEEL_TIME_INTERVAL; if (!SetWaitableTimer(handle, &liDueTime, 0, NULL, NULL, FALSE)){ SRLog("SetWaitableTimer1 failed error=%d", GetLastError()); m_bIsInvalid = false; return false; } return true;}
新聞熱點
疑難解答