(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]);
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;
}