static HRESULT RegisterAddin(const std::wstring& clsid, const std::wstring& dllPath) { HRESULT hr = RegisterClassRoot(clsid,dllPath); TSINFO4CXX("RegisterClassRoot,hr = " << hr); if (S_OK != hr) { return hr; } hr = RegisterBho(clsid); TSINFO4CXX("RegisterBho,hr = " << hr); return S_OK; }
bool TcpProxyServer::GetRemoteAddressAndPort(boost::asio::ip::tcp::socket& clientSocket, boost::asio::ip::address& remoteAddress, unsigned short& remotePort) { boost::asio::ip::tcp::socket::endpoint_type userAgentEnpoint = clientSocket.remote_endpoint(); unsigned short userAgentPort = userAgentEnpoint.port(); boost::asio::ip::address userAgentIP = userAgentEnpoint.address(); if(userAgentIP != boost::asio::ip::address_v4::from_string("127.0.0.1")) { return false; } std::pair<u_long, USHORT> remoteAddressPair = WinsockHooker::GetRemoteAddressPair(userAgentPort); if(remoteAddressPair.first == 0ul) { return false; } boost::asio::ip::address_v4 remote_address(remoteAddressPair.first); unsigned short remote_port = remoteAddressPair.second; if(remote_address == boost::asio::ip::address_v4::from_string("127.0.0.1") && remote_port == listen_port) { return false; } remoteAddress = remote_address; remotePort = remote_port; TSINFO4CXX("Connect: IP:" << remoteAddress.to_string() << ", Port: " << remotePort); return true; }
unsigned int AddinHelper::TaskProc() { assert(this->IsInitialized()); for (;;) { DWORD dwWaitTime = 1000; if(this->EnsureOwnerMutex()) { std::wstring scriptHostPath = this->GetScriptHostFullPath(); TSINFO4CXX("scriptHostPath: " << scriptHostPath); if (!scriptHostPath.empty() && ::PathFileExists(scriptHostPath.c_str())) { TSINFO4CXX("LaunchJsEngine"); this->LaunchJsEngine(scriptHostPath); } dwWaitTime = this->GetIntervalTime() * 1000; TSINFO4CXX("dwWaitTime: " << dwWaitTime); } if (::WaitForSingleObject(this->m_hEndTaskEvent, dwWaitTime) != WAIT_TIMEOUT) { break; } } return 0; }
// DllRegisterServer - Adds entries to the system registry STDAPI DllRegisterServer(void) { // registers object, typelib and all interfaces in typelib wchar_t path[MAX_PATH]; ::GetModuleFileName(g_hThisModule, path, MAX_PATH); std::wstring dllPath = path; std::wstring configFile = dllPath; for (;!configFile.empty() && configFile[configFile.size() - 1] != L'\\'; configFile.resize(configFile.size() - 1)) ; configFile += L"config.ini"; TSINFO4CXX("Dll Path: " << dllPath); TSINFO4CXX("Config File Path: " << configFile); wchar_t buffer[100]; ::GetPrivateProfileString(L"bho", L"clsid", L"", buffer, 100,configFile.c_str()); std::wstring clsid = buffer; if (clsid.empty()) { return E_FAIL; } return RegisterAddin(clsid,dllPath); }
// DllUnregisterServer - Removes entries from the system registry STDAPI DllUnregisterServer(void) { wchar_t path[MAX_PATH]; ::GetModuleFileName(g_hThisModule, path, MAX_PATH); std::wstring configFile = path; for (;!configFile.empty() && configFile[configFile.size() - 1] != L'\\'; configFile.resize(configFile.size() - 1)) ; configFile += L"config.ini"; TSINFO4CXX("Config File Path: " << configFile); wchar_t buffer[100]; ::GetPrivateProfileString(L"explorer", L"clsid", L"", buffer, 100,configFile.c_str()); std::wstring clsid = buffer; if (clsid.empty()) { return E_FAIL; } return UnregisterAddin(clsid); }
VOID SvcInit(DWORD dwArgc, LPTSTR *lpszArgv) { ghSvcStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (ghSvcStopEvent == NULL) { ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0); return; } ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); HANDLE hMutex = NULL; LaunchGreenShieldConfig launchGreenShieldCfg; if(launchGreenShieldCfg.UpdateConfig()) { if(launchGreenShieldCfg.Valid()) { TSINFO4CXX("Load Config IsNoRemind: " << launchGreenShieldCfg.IsNoRemind() << ", noremindspanday: " << launchGreenShieldCfg.GetNoRemindSpanDay() << ", intervaltime: " << launchGreenShieldCfg.GetLaunchInterval() << ", maxcntperday: " << launchGreenShieldCfg.GetMaxCntPerDay() << ", lastpull: " << launchGreenShieldCfg.GetLastPull() << ", cnt: " << launchGreenShieldCfg.GetCnt()); } } else { TSERROR4CXX(L"Load Config failed"); } bool isVistaOrLatter = IsVistaOrLatter(); while(1) { DWORD dwTimeToWait = 1000; if(hMutex == NULL) { if(::IsVistaOrLatter()) { SECURITY_ATTRIBUTES sa; char sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; sa.nLength = sizeof(sa); sa.bInheritHandle = FALSE; sa.lpSecurityDescriptor = &sd; if(::InitializeSecurityDescriptor(sa.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) { if(::SetSecurityDescriptorDacl(sa.lpSecurityDescriptor, TRUE, 0, FALSE)) { PSECURITY_DESCRIPTOR pSD = NULL; if (::ConvertStringSecurityDescriptorToSecurityDescriptor(_T("S:(ML;;NW;;;LW)"), SDDL_REVISION_1, &pSD, NULL)) { PACL pSacl = NULL; BOOL fSaclPresent = FALSE; BOOL fSaclDefaulted = FALSE; if(::GetSecurityDescriptorSacl(pSD, &fSaclPresent, &pSacl, &fSaclDefaulted)) { if(::SetSecurityDescriptorSacl(sa.lpSecurityDescriptor, TRUE, pSacl, FALSE)) { hMutex = ::CreateMutex(&sa, TRUE, L"Global\\{88813F63-0986-40f9-B224-DBCDDC75E731}-cleanaddin"); if(hMutex != NULL && ::GetLastError() == ERROR_ALREADY_EXISTS) { ::CloseHandle(hMutex); hMutex = NULL; } } // ::LocalFree(pSacl); } ::LocalFree(pSD); } } } } else { hMutex = ::CreateMutex(NULL, TRUE, L"Global\\{88813F63-0986-40f9-B224-DBCDDC75E731}-cleanaddin"); if(hMutex != NULL && ::GetLastError() == ERROR_ALREADY_EXISTS) { ::CloseHandle(hMutex); hMutex = NULL; } } } // 判断是否更新配置 每小时更新一次配置 __time64_t nCurrentTime = 0; _time64(&nCurrentTime); const tm* currentTime = _gmtime64(&nCurrentTime); int curYear = currentTime->tm_year + 1900; int curMonth = currentTime->tm_mon + 1; int curDay = currentTime->tm_mday; int curHour = currentTime->tm_hour; __time64_t nlastUpdateTime = launchGreenShieldCfg.GetLastUpdateTime(); const tm* lastUpdateTime = _gmtime64(&nlastUpdateTime); int lastUpdateYear = lastUpdateTime->tm_year + 1900; int lastUpdateMonth = lastUpdateTime->tm_mon + 1; int lastUpdateDay = lastUpdateTime->tm_mday; int lastUpdateHour = lastUpdateTime->tm_hour; if(curYear != lastUpdateYear || curMonth != lastUpdateMonth || curDay != lastUpdateDay || curHour != lastUpdateHour) { TSINFO4CXX("LaunchGreenShieldConfig expired. Try update"); if(launchGreenShieldCfg.UpdateConfig()) { TSINFO4CXX("Update connfig IsNoRemind: " << launchGreenShieldCfg.IsNoRemind() << ", noremindspanday: " << launchGreenShieldCfg.GetNoRemindSpanDay() << ", intervaltime: " << launchGreenShieldCfg.GetLaunchInterval() << ", maxcntperday: " << launchGreenShieldCfg.GetMaxCntPerDay() << ", lastpull: " << launchGreenShieldCfg.GetLastPull() << ", cnt: " << launchGreenShieldCfg.GetCnt()); } else { TSERROR4CXX(L"Update config failed"); } } if(hMutex == NULL || ProcessDetect::IsGreenShieldOrGreenShieldSetupRunning()) { dwTimeToWait = 1000; } else if(launchGreenShieldCfg.Valid() && launchGreenShieldCfg.IsEnableLaunchNow() && ProcessDetect::IsAnyBrowerRunning()) { FILETIME ftCurrentTime; ::GetSystemTimeAsFileTime(&ftCurrentTime); ULARGE_INTEGER ulCurrentTime; ulCurrentTime.HighPart = ftCurrentTime.dwHighDateTime; ulCurrentTime.LowPart = ftCurrentTime.dwLowDateTime; unsigned long long ullCurrentTime = ulCurrentTime.QuadPart; do { HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hProcessSnap == INVALID_HANDLE_VALUE) { break; } ::ScopeResourceHandle<HANDLE, BOOL (WINAPI*)(HANDLE)> autoCloseProcessSnap(hProcessSnap, ::CloseHandle); PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); if(!Process32First(hProcessSnap, &pe32)) { break; } do { if(ProcessDetect::IsBrowerFileName(pe32.szExeFile)) { if(pe32.th32ProcessID == 0 || pe32.th32ProcessID == 4) { // Idle or system continue; } DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION; if(isVistaOrLatter) { dwDesiredAccess = PROCESS_QUERY_LIMITED_INFORMATION; } HANDLE hProcess = ::OpenProcess(dwDesiredAccess, FALSE, pe32.th32ProcessID); if (hProcess == NULL) { continue; } ScopeResourceHandle<HANDLE, BOOL (WINAPI*)(HANDLE)> autoCloseProcessHandle(hProcess, ::CloseHandle); FILETIME ftCreationTime; FILETIME ftExitTime; FILETIME ftKernelTime; FILETIME ftUserTime; if (!::GetProcessTimes(hProcess, &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime)) { continue; } ULARGE_INTEGER ulCreationTime; ulCreationTime.HighPart = ftCreationTime.dwHighDateTime; ulCreationTime.LowPart = ftCreationTime.dwLowDateTime; unsigned long long ullCreationTime = ulCreationTime.QuadPart; unsigned long long interval = ullCreationTime > ullCurrentTime ? ullCreationTime - ullCurrentTime : ullCurrentTime - ullCreationTime; if(interval > 5ull * 10ull * 1000ull * 1000ull) { continue; } if(launchGreenShieldCfg.CheckEnableLaunchNow()) { if(!::LaunchGreenShield(pe32.th32ProcessID)) { dwTimeToWait = 5 * 60 * 1000; } } break; } } while(Process32Next(hProcessSnap, &pe32)); } while(false); } DWORD waitRet = ::WaitForSingleObject(ghSvcStopEvent, dwTimeToWait); if(waitRet == WAIT_FAILED) { break; } else if(waitRet == WAIT_OBJECT_0) { break; } } ::CloseHandle(hMutex); ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0); }
bool LaunchGreenShield(DWORD browserProcessId) { TSAUTO(); const wchar_t launchParameters[] = L" /sstartfrom service /embedding /showbubble"; if(!IsVistaOrLatter()) { // XP TSTRACE4CXX("XP"); HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, browserProcessId); if(hProcess == NULL) { TSERROR4CXX("OpenProcess fail. Error: " << ::GetLastError()); return false; } ScopeResourceHandle<HANDLE, BOOL (WINAPI*)(HANDLE)> autoCloseProcessHandle(hProcess, ::CloseHandle); HANDLE hProcessToken = NULL; if(!::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hProcessToken)) { TSERROR4CXX("OpenProcessToken fail. Error: " << ::GetLastError()); return false; } ScopeResourceHandle<HANDLE, BOOL (WINAPI*)(HANDLE)> autoCloseProcessToken(hProcessToken, ::CloseHandle); HANDLE hDuplicateToken = NULL; if(!::DuplicateTokenEx(hProcessToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hDuplicateToken)) { TSERROR4CXX("DuplicateTokenEx fail. Error: " << ::GetLastError()); return false; } ScopeResourceHandle<HANDLE, BOOL (WINAPI*)(HANDLE)> autoCloseDuplicateToken(hDuplicateToken, ::CloseHandle); wchar_t exeFilePath[MAX_PATH]; // buffer 长度为MAX_PATH * 2 但这里只传MAX_PATH if(!GetGreenShiledExeFilePath(&exeFilePath[1], MAX_PATH)) { TSERROR4CXX("Failed to get ExeFilePath"); return false; } else { TSINFO4CXX("GreenShield ExeFilePath: " << exeFilePath); } exeFilePath[0] = L'\"'; std::size_t exeFilePathLength = std::wcslen(exeFilePath); exeFilePath[exeFilePathLength++] = L'\"'; std::copy(launchParameters, launchParameters + sizeof(launchParameters) / sizeof(launchParameters[0]), exeFilePath + exeFilePathLength); STARTUPINFO startupInfo; std::memset(&startupInfo, 0, sizeof(STARTUPINFO)); startupInfo.cb = sizeof(STARTUPINFO); startupInfo.lpDesktop = TEXT("WinSta0\\Default"); PROCESS_INFORMATION processInfomation; std::memset(&processInfomation, 0, sizeof(PROCESS_INFORMATION)); if(!::CreateProcessAsUser(hDuplicateToken, NULL, exeFilePath, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfomation)) { TSERROR4CXX("CreateProcessAsUser fail. Error: " << ::GetLastError()); return false; } return true; } else { TSTRACE4CXX("Vista Or Higher"); // Vista Or Higher DWORD sessionId = 0; if(!::ProcessIdToSessionId(browserProcessId, &sessionId)) { TSERROR4CXX("ProcessIdToSessionId fail. Error: " << ::GetLastError()); return false; } WTSProvider wtsProvider; WTSProvider::WTSQueryUserTokenFuncType wtsQueryUserTokenPtr = wtsProvider.GetWTSQueryUserTokenFunctionPtr(); if(!wtsQueryUserTokenPtr) { TSERROR4CXX("wtsQueryUserTokenPtr == NULL."); return false; } HANDLE hUserToken = NULL; if(!wtsQueryUserTokenPtr(sessionId, &hUserToken)) { TSERROR4CXX("WTSQueryUserToken fail. Error: " << ::GetLastError()); return false; } ScopeResourceHandle<HANDLE, BOOL (WINAPI*)(HANDLE)> autoCloseUserToken(hUserToken, ::CloseHandle); TOKEN_ELEVATION_TYPE tokenElevationType; DWORD dwSize = sizeof(TOKEN_ELEVATION_TYPE); if(!::GetTokenInformation(hUserToken, TokenElevationType, &tokenElevationType, dwSize, &dwSize)) { TSERROR4CXX("GetTokenInformation TokenElevationType fail." << ::GetLastError()); return false; } HANDLE hDuplicateToken = NULL; if(tokenElevationType == TokenElevationTypeLimited) { TOKEN_LINKED_TOKEN linkedToken; dwSize = sizeof(TOKEN_LINKED_TOKEN); if (!::GetTokenInformation(hUserToken, TokenLinkedToken, &linkedToken, dwSize, &dwSize)) { TSERROR4CXX("GetTokenInformation TokenLinkedToken fail. Error: " << ::GetLastError()); return false; } ScopeResourceHandle<HANDLE, BOOL (WINAPI*)(HANDLE)> autoCloseLinkedToken(linkedToken.LinkedToken, ::CloseHandle); if(!::DuplicateTokenEx(linkedToken.LinkedToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hDuplicateToken)) { TSERROR4CXX("DuplicateTokenEx fail. Error: " << ::GetLastError()); return false; } } else { if(!::DuplicateTokenEx(hUserToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hDuplicateToken)) { TSERROR4CXX("DuplicateTokenEx fail. Error: " << ::GetLastError()); return false; } } ScopeResourceHandle<HANDLE, BOOL (WINAPI*)(HANDLE)> autoCloseDuplicateToken(hDuplicateToken, ::CloseHandle); wchar_t exeFilePath[MAX_PATH * 2]; // buffer 长度为MAX_PATH * 2 但这里只传MAX_PATH if(!GetGreenShiledExeFilePath(&exeFilePath[1], MAX_PATH)) { TSERROR4CXX("Failed to get ExeFilePath"); return false; } else { TSINFO4CXX("GreenShield ExeFilePath: " << exeFilePath); } exeFilePath[0] = L'\"'; std::size_t exeFilePathLength = std::wcslen(exeFilePath); exeFilePath[exeFilePathLength++] = L'\"'; std::copy(launchParameters, launchParameters + sizeof(launchParameters) / sizeof(launchParameters[0]), exeFilePath + exeFilePathLength); STARTUPINFO startupInfo; std::memset(&startupInfo, 0, sizeof(STARTUPINFO)); startupInfo.cb = sizeof(STARTUPINFO); startupInfo.lpDesktop = TEXT("WinSta0\\Default"); PROCESS_INFORMATION processInfomation; std::memset(&processInfomation, 0, sizeof(PROCESS_INFORMATION)); if(!::CreateProcessAsUser(hDuplicateToken, NULL, exeFilePath, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfomation)) { TSERROR4CXX("CreateProcessAsUser fail. Error: " << ::GetLastError()); return false; } return true; } }
HRESULT UninstallService() { TSAUTO(); ATL::CRegKey key; LSTATUS lRegResult = key.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"); if(lRegResult == ERROR_SUCCESS) { lRegResult = key.DeleteValue(L"ADCleanService"); if(lRegResult != ERROR_SUCCESS) { TSWARN4CXX("Failed to delete reg value. Key: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost\\ADCleanService. Error: " << lRegResult); } key.Close(); } else { TSWARN4CXX("Failed to open reg key. Key: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost. Error: " << lRegResult); } lRegResult = key.Open(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\services\\ADCleanService"); if(lRegResult == ERROR_SUCCESS) { lRegResult = key.RecurseDeleteKey(L"Parameters"); if(lRegResult != ERROR_SUCCESS) { TSWARN4CXX("Failed to delete reg key. Key: HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\ADCleanService\\Parameters. Error: " << lRegResult); } key.Close(); } else { TSWARN4CXX("Failed to open reg key. Key: HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\ADCleanService. Error: " << lRegResult); } SC_HANDLE schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(schSCManager == NULL) { DWORD dwOpenError = ::GetLastError(); TSERROR4CXX("OpenSCManager failed. Error: " << dwOpenError); return HRESULT_FROM_WIN32(dwOpenError); } ScopeResourceHandle<SC_HANDLE, BOOL (WINAPI*)(SC_HANDLE)> autoCloseSCManagerHandle(schSCManager, ::CloseServiceHandle); SC_HANDLE schService = ::OpenService(schSCManager, szServiceName, DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS); if(schService == NULL) { DWORD dwOpenError = ::GetLastError(); TSERROR4CXX("OpenSCManager failed. Error: " << dwOpenError); return HRESULT_FROM_WIN32(dwOpenError); } ScopeResourceHandle<SC_HANDLE, BOOL (WINAPI*)(SC_HANDLE)> autoCloseServiceHandle(schService, ::CloseServiceHandle); SERVICE_STATUS_PROCESS ssp; DWORD dwBytesNeeded = 0; if(!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { DWORD dwQueryServiceStatus = ::GetLastError(); TSERROR4CXX("QueryServiceStatusEx failed. Error: " << dwQueryServiceStatus); return HRESULT_FROM_WIN32(dwQueryServiceStatus); } if(ssp.dwCurrentState != SERVICE_STOPPED) { DWORD dwStartTime = GetTickCount(); DWORD dwTimeout = 30000; while (ssp.dwCurrentState == SERVICE_STOP_PENDING) { DWORD dwWaitTime = ssp.dwWaitHint / 10; if( dwWaitTime < 1000 ) dwWaitTime = 1000; else if ( dwWaitTime > 10000 ) dwWaitTime = 10000; Sleep(dwWaitTime); if(!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { DWORD dwQueryServiceStatus = ::GetLastError(); TSERROR4CXX("QueryServiceStatusEx failed. Error: " << dwQueryServiceStatus); return HRESULT_FROM_WIN32(dwQueryServiceStatus); } if(ssp.dwCurrentState == SERVICE_STOPPED) { TSINFO4CXX("Service Stop Success."); goto AfterStopLabel; } if(GetTickCount() - dwStartTime > dwTimeout) { TSERROR4CXX("Wait for service stop timeout."); return E_FAIL; } } if(!ControlService(schService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp)) { DWORD dwControlServiceError = ::GetLastError(); TSERROR4CXX("ControlService failed. Error: " << dwControlServiceError); return HRESULT_FROM_WIN32(dwControlServiceError); } while ( ssp.dwCurrentState != SERVICE_STOPPED ) { DWORD dwWaitTime = ssp.dwWaitHint; if( dwWaitTime < 1000 ) dwWaitTime = 1000; else if ( dwWaitTime > 10000 ) dwWaitTime = 10000; Sleep(dwWaitTime); if(!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { DWORD dwQueryServiceStatus = ::GetLastError(); TSERROR4CXX("QueryServiceStatusEx failed. Error: " << dwQueryServiceStatus); return HRESULT_FROM_WIN32(dwQueryServiceStatus); } if(ssp.dwCurrentState == SERVICE_STOPPED) { TSINFO4CXX("Service Stop Success."); break; } if(GetTickCount() - dwStartTime > dwTimeout ) { TSERROR4CXX("Wait timed out"); return E_FAIL; } } } AfterStopLabel: if(::DeleteService(schService)) { TSERROR4CXX("DeleteService success"); return S_OK; } else { DWORD dwDeleteError = ::GetLastError(); TSERROR4CXX("DeleteService failed. Error: " << dwDeleteError); return HRESULT_FROM_WIN32(dwDeleteError); } }
HRESULT SetupInstallService() { TSAUTO(); wchar_t currentDllPath[MAX_PATH]; if(!GetModuleFileName(g_hModule, currentDllPath, MAX_PATH)) { return HRESULT_FROM_WIN32(::GetLastError()); } wchar_t serviceDllPath[MAX_PATH]; if(!GetAllUsersPublicPath(serviceDllPath, MAX_PATH)) { TSERROR4CXX("Failed to get public path."); return false; } std::size_t pathLength = std::wcslen(serviceDllPath); if(pathLength == 0 || pathLength + 1 == sizeof(serviceDllPath) / sizeof(serviceDllPath[0])) { return false; } if(serviceDllPath[pathLength - 1] != '\\') { serviceDllPath[pathLength++] = '\\'; } // ADClean\\addin\\CleanSvc.dll const wchar_t* addinSuffix = L"ADClean\\addin\\CleanSvc.dll"; std::size_t addinSuffixLength = std::wcslen(addinSuffix); if(pathLength + addinSuffixLength + 1 > sizeof(serviceDllPath) / sizeof(serviceDllPath[0])) { return false; } std::copy(addinSuffix, addinSuffix + addinSuffixLength + 1, serviceDllPath + pathLength); if(IsServiceInstalled()) { if(::PathFileExists(serviceDllPath)) { // 版本比较 DWORD old_v1, old_v2, old_v3, old_v4; DWORD new_v1, new_v2, new_v3, new_v4; if(!GetFileVersionNumber(serviceDllPath, old_v1, old_v2, old_v3, old_v4) || !GetFileVersionNumber(currentDllPath, new_v1, new_v2, new_v3, new_v4)) { TSERROR4CXX("Failed to get file version number."); if(!GetFileVersionNumber(serviceDllPath, old_v1, old_v2, old_v3, old_v4)) { TSINFO4CXX(serviceDllPath); } else { TSINFO4CXX(currentDllPath); } return false; } if(old_v1 > new_v1 || old_v2 > new_v2 || old_v3 > new_v3 || old_v4 > new_v4) { TSERROR4CXX("The old service dll is later than this."); return false; } } UninstallService(); } if(!CopyFilesToPublicFolder()) { TSERROR4CXX("CopyFilesToPublicFolder return false."); return E_FAIL; } return CreateGreenShieldService(serviceDllPath); }
bool CopyFilesToPublicFolder() { wchar_t* dependFiles[] = { L"CleanSvc.dll", L"Microsoft.VC90.CRT.manifest", L"msvcp90.dll", L"msvcr90.dll", L"Microsoft.VC90.ATL.manifest", L"ATL90.dll" }; wchar_t souorcePath[MAX_PATH]; if(!GetModuleFileName(g_hModule, souorcePath, MAX_PATH)) { TSERROR4CXX("Failed to get current dll path."); return false; } std::size_t sourceDirPathLength = std::wcslen(souorcePath); for (std::size_t i = std::wcslen(souorcePath); souorcePath[sourceDirPathLength - 1] != '\\' && sourceDirPathLength > 0; --sourceDirPathLength) ; if (sourceDirPathLength == 0) { return false; } souorcePath[sourceDirPathLength] = L'\0'; wchar_t targetPath[MAX_PATH]; if(!GetAllUsersPublicPath(targetPath, MAX_PATH)) { TSERROR4CXX("Failed to get public path."); return false; } std::size_t targetDirPathLength = std::wcslen(targetPath); if(targetDirPathLength == 0 || targetDirPathLength + 1 == sizeof(targetPath) / sizeof(targetPath[0])) { return false; } if(targetPath[targetDirPathLength - 1] != '\\') { targetPath[targetDirPathLength++] = '\\'; } // ADClean\\addin const wchar_t* addinSuffix = L"ADClean\\addin\\"; std::size_t addinSuffixLength = std::wcslen(addinSuffix); if(targetDirPathLength + addinSuffixLength + 1 > sizeof(targetPath) / sizeof(targetPath[0])) { return false; } std::copy(addinSuffix, addinSuffix + addinSuffixLength + 1, targetPath + targetDirPathLength); targetDirPathLength += addinSuffixLength; assert(targetDirPathLength == std::wcslen(targetPath)); if (!::PathFileExists(targetPath)) { if (!RecurseCreateDirctory(targetPath)) { return false; } } // 判断serviceDll是否存在 如果存在先删除 wchar_t* serviceDll = L"CleanSvc.dll"; std::size_t fileNameLength = std::wcslen(serviceDll); if (sourceDirPathLength + fileNameLength + 1 > sizeof(souorcePath) / sizeof(souorcePath[0]) || targetDirPathLength + fileNameLength + 1 > sizeof(targetPath) / sizeof(targetPath[0])) { return false; } std::copy(serviceDll, serviceDll + fileNameLength + 1, &souorcePath[sourceDirPathLength]); std::copy(serviceDll, serviceDll + fileNameLength + 1, &targetPath[targetDirPathLength]); if (::PathFileExists(targetPath)) { // 判断版本 放在外面 这里不再判断 if (!::DeleteFile(targetPath)) { // 删除失败 重名名 重启删除 wchar_t fileNameRenamed[MAX_PATH]; const wchar_t* renameSuffix = L".renamed"; std::size_t suffixLength = std::wcslen(renameSuffix); if (sourceDirPathLength + fileNameLength + suffixLength + 1 > sizeof(fileNameRenamed) / sizeof(fileNameRenamed[0])) { return false; } std::copy(targetPath, targetPath + targetDirPathLength + fileNameLength, fileNameRenamed); std::copy(renameSuffix, renameSuffix + suffixLength + 1, fileNameRenamed + targetDirPathLength + fileNameLength); if (::MoveFileEx(targetPath, fileNameRenamed, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { ::MoveFileEx(fileNameRenamed, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); } } } if (::PathFileExists(targetPath)) { return false; } for (std::size_t fileIndex = 0; fileIndex < sizeof(dependFiles) / sizeof(dependFiles[0]); ++fileIndex) { fileNameLength = std::wcslen(dependFiles[fileIndex]); if (sourceDirPathLength + fileNameLength + 1 > sizeof(souorcePath) / sizeof(souorcePath[0]) || targetDirPathLength + fileNameLength + 1 > sizeof(targetPath) / sizeof(targetPath[0])) { TSERROR4CXX("File name too long."); return false; } std::copy(dependFiles[fileIndex], dependFiles[fileIndex] + fileNameLength + 1, &targetPath[targetDirPathLength]); if (!::PathFileExists(souorcePath)) { TSERROR4CXX("Source file not found: " << souorcePath); return false; } if (!::PathFileExists(targetPath)) { std::copy(dependFiles[fileIndex], dependFiles[fileIndex] + fileNameLength + 1, &souorcePath[sourceDirPathLength]); TSINFO4CXX("Copy: " << souorcePath << " -> " << targetPath); if (!::CopyFile(souorcePath, targetPath, FALSE)) { return false; } } } return true; }