PLMTool/main.cpp
2024-02-28 10:20:51 +08:00

381 lines
11 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Packet.h"
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <Windows.h>
#include <string>
#include <tlhelp32.h>
#include <sstream>
#include <tchar.h>
#include "easylog/easylogging++.h"
INITIALIZE_EASYLOGGINGPP
// Windows服务的服务名
TCHAR SERVICE_NAME[] = _T("MyPcap");
SERVICE_STATUS_HANDLE g_ServiceStatusHandle;
SERVICE_STATUS g_ServiceStatus;
DWORD g_ThreadID;
std::wofstream g_ofs;
// 服务主函数
VOID WINAPI ServiceMain(DWORD argc, LPWSTR* argv);
// 服务控制处理函数
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode);
void EasyLogConf()
{
//加载默认配置 init log
el::Configurations conf;
//设置为默认
conf.setToDefault();
//设置日志输出格式
conf.setGlobally(el::ConfigurationType::Format, "%datetime %level [%fbase|%line] %msg");
//设置日志文件目录以及文件名
conf.setGlobally(el::ConfigurationType::Filename, "logs\\%datetime{%Y%M%d}.log");
//启用日志
conf.setGlobally(el::ConfigurationType::Enabled, "true");
//是否写入文件
conf.setGlobally(el::ConfigurationType::ToFile, "true");
//是否输出控制台
conf.setGlobally(el::ConfigurationType::ToStandardOutput, "false");
//设置配置文件
el::Loggers::reconfigureAllLoggers(conf); //加载配置文件
}
std::wstring GetStrNow()
{
wchar_t buffer[128];
SYSTEMTIME snow;
GetLocalTime(&snow);
swprintf_s(buffer, sizeof(buffer), L"%04d-%02d-%02d %02d:%02d:%02d", snow.wYear, snow.wMonth, snow.wDay, snow.wHour, snow.wMinute, snow.wSecond);
return std::wstring(buffer);
}
void LogEvent(LPTSTR chmsg) {
HANDLE hEventSource;
LPTSTR lpszStrings[1];
lpszStrings[0] = chmsg;
hEventSource = RegisterEventSource(NULL, SERVICE_NAME);
if (hEventSource != NULL)
{
ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*)&lpszStrings[0], NULL);
DeregisterEventSource(hEventSource);
}
}
int execCmdUseGetline(const char* cmd, std::wofstream& ofs)
{
FILE* pipe = _popen(cmd, "r");
if (!pipe)
{
return -1;
}
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
wchar_t buf[512] = { 0 };
ofs << GetStrNow() << "\n";
ofs.flush();
while (fgetws(buf, 512, pipe) != NULL)
{
if (snapshot == INVALID_HANDLE_VALUE) {
ofs << buf;
ofs.flush();
}
else {
std::wstring str(buf);
int frel = str.find(L"TCP");
int fre2 = str.find(L"UDP");
if (frel != -1)
{
std::wistringstream iss(str);
std::wstring protocol, localAddress, remoteAddress, state, processName;
int processId;
iss >> protocol >> localAddress >> remoteAddress >> state >> processId;
PROCESSENTRY32 processEntry;
processEntry.dwSize = sizeof(PROCESSENTRY32);
// 遍历进程列表
if (Process32First(snapshot, &processEntry)) {
do {
// 如果找到目标进程,则返回其名称
if (processEntry.th32ProcessID == processId) {
processName = processEntry.szExeFile;
break;
}
} while (Process32Next(snapshot, &processEntry));
}
ofs << protocol << "," << localAddress << "," << remoteAddress << "," << state << "," << processId << "," << processName << "\n";
ofs.flush();
}
if (fre2 != -1) {
std::wistringstream iss(str);
std::wstring protocol, localAddress, remoteAddress, processName;
int processId;
// 读取并输出每个单词
iss >> protocol >> localAddress >> remoteAddress >> processId >> processName;
PROCESSENTRY32 processEntry;
processEntry.dwSize = sizeof(PROCESSENTRY32);
// 遍历进程列表
if (Process32First(snapshot, &processEntry)) {
do {
// 如果找到目标进程,则返回其名称
if (processEntry.th32ProcessID == processId) {
processName = processEntry.szExeFile;
break;
}
} while (Process32Next(snapshot, &processEntry));
}
ofs << protocol << "," << localAddress << "," << remoteAddress << "," << "none" << "," << processId << "," << processName << "\n";
ofs.flush();
}
}
}
ofs << "\n";
ofs.flush();
_pclose(pipe);
if (snapshot != INVALID_HANDLE_VALUE)CloseHandle(snapshot);
return 0;
}
int ConsoleMain()
{
LOG(DEBUG) << "SimpleService: Service is running..." ;
Packet* pk = new Packet();
LOG(DEBUG) << "packet new" << std::endl;
pk->Init();
pk->Run();
LOG(DEBUG) << "packet end" << std::endl;
delete pk;
pk = nullptr;
return 0;
}
VOID WINAPI ServiceMain(DWORD argc, LPWSTR* argv)
{
LOG(DEBUG) << "ServiceMain START...";
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
// 注册服务控制处理函数
g_ServiceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
if (g_ServiceStatusHandle == NULL)
{
LOG(ERROR) << "Handler not install";
return;
}
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
g_ServiceStatus.dwWin32ExitCode = S_OK;
g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0;
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
// 在 ServiceMain 中调用控制台程序的主函数
ConsoleMain();
// 设置服务状态为停止
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus)){
LOG(ERROR) << "SetServiceStatus failed, error code: " << GetLastError();
}
return;
}
void Init()
{
g_ServiceStatusHandle = NULL;
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwServiceSpecificExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0;
}
bool IsInstalled()
{
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL) {
LOG(ERROR) << "OpenSCManager error..."<<GetLastError();
return false;
}
SC_HANDLE hService = ::OpenService(hSCM, SERVICE_NAME, SERVICE_QUERY_CONFIG);
if (hService == NULL) {
::CloseServiceHandle(hSCM);
LOG(ERROR) << "OpenService error..."<<GetLastError() ;
return false;
}
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return false;
}
bool Install()
{
if (IsInstalled())return true;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)return false;
TCHAR szFilePath[MAX_PATH];
::GetModuleFileName(NULL, szFilePath, MAX_PATH);
SC_HANDLE hService = ::CreateService(hSCM, SERVICE_NAME, SERVICE_NAME, SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, _T(""), NULL, NULL);
if (hService == NULL) {
::CloseServiceHandle(hSCM);
LOG(ERROR) << "CreateService false...";
return false;
}
// 创建服务后立即启动
if (!StartService(hService, 0, NULL)){
LOG(ERROR) << " StartService false...";
}
else {
printf("服务启动成功...");
LOG(DEBUG) << " 服务启动成功...";
}
// 设置延迟自动启动信息
SERVICE_DELAYED_AUTO_START_INFO delayedStartInfo{};
delayedStartInfo.fDelayedAutostart = TRUE;
// 修改服务配置 设置为延迟启动开机1-2分钟内启动否则自动启动会报错
if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, &delayedStartInfo)) {
LOG(ERROR) << "Failed to change service configuration";
}
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
LOG(DEBUG) << "Install end...";
return true;
}
bool Uninstall()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL){
std::cout << "打开SCManager失败:" << GetLastError() << std::endl;
return false;
}
schService = OpenService(schSCManager, TEXT("MyPcap"), SERVICE_ALL_ACCESS);
if (schService == NULL) {
std::cout << "打开服务失败:" << GetLastError() << std::endl;
CloseServiceHandle(schSCManager);
return false;
}
bool result = true;
SERVICE_STATUS status;
::ControlService(schService, SERVICE_CONTROL_STOP, &status);
if (!DeleteService(schService)){
std::cout << "删除服务失败:" << GetLastError() << std::endl;
result = false;
}
else{
printf("服务删除成功");
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return result;
}
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
{
switch (CtrlCode)
{
case SERVICE_CONTROL_STOP:
//设置服务状态为停止
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwCheckPoint = 1;
if (!SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus))
{
std::cerr << "SetServiceStatus failed, error code: " << GetLastError() << std::endl;
}
Sleep(500);
// 设置服务状态为停止
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus))
{
std::cerr << "SetServiceStatus failed, error code: " << GetLastError() << std::endl;
}
PostThreadMessage(g_ThreadID, WM_CLOSE, 0, 0);
break;
case SERVICE_CONTROL_SHUTDOWN:
exit(0);
break;
default:
break;
}
return;
}
int APIENTRY _tWinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){
EasyLogConf(); //easylog配置
Init();
g_ThreadID = ::GetCurrentThreadId();
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTIONW)ServiceMain },
{ NULL, NULL }
};
if (_wcsicmp(lpCmdLine, _T("/install")) == 0)
{
LOG(DEBUG) << "install start...";
Install();
}
else if (_wcsicmp(lpCmdLine, _T("/uninstall")) == 0)
{
LOG(DEBUG) << "uninstall start...";
if (!Uninstall()) {
LOG(DEBUG) << "uninstall error(" << GetLastError() << ")...";
}
}
else {
LOG(DEBUG) << "start...";
if (!::StartServiceCtrlDispatcher(ServiceTable))
{
LOG(DEBUG) << "start error(" << GetLastError() << ")...";
}
}
return 0;
}