120 lines
4.6 KiB
C++
120 lines
4.6 KiB
C++
// NetTunnelSvr.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
|
||
//
|
||
#include <Windows.h>
|
||
#include <strsafe.h>
|
||
#include <tchar.h>
|
||
|
||
#define WG_TUNNEL_SVR_NAME TEXT("WireGuard_DLL_SVR")
|
||
|
||
typedef BOOL(WINAPI WIREGUARD_TUNNEL_SERVICE_FUNC)(_In_z_ LPCWSTR Name);
|
||
static WIREGUARD_TUNNEL_SERVICE_FUNC *WireGuardTunnelService;
|
||
|
||
static void LogToSystemEventLog(int wErrorType, int wCustumerCode, const TCHAR *szMsg) {
|
||
HANDLE hEventSource;
|
||
DWORD dwEventIdentifer;
|
||
|
||
switch (wErrorType) {
|
||
case EVENTLOG_SUCCESS:
|
||
case EVENTLOG_AUDIT_SUCCESS:
|
||
dwEventIdentifer = 0x00;
|
||
break;
|
||
case EVENTLOG_INFORMATION_TYPE:
|
||
dwEventIdentifer = 0x01;
|
||
break;
|
||
case EVENTLOG_WARNING_TYPE:
|
||
dwEventIdentifer = 0x02;
|
||
break;
|
||
case EVENTLOG_ERROR_TYPE:
|
||
case EVENTLOG_AUDIT_FAILURE:
|
||
dwEventIdentifer = 0x03;
|
||
break;
|
||
default:
|
||
dwEventIdentifer = 0;
|
||
break;
|
||
}
|
||
// 移位获得Sev,前面给出的 wErrorType 为 EVENTLOG_ERROR_TYPE,对应着下图 “级别” 一列显示“错误”图标
|
||
dwEventIdentifer <<= 30;
|
||
dwEventIdentifer |= static_cast<WORD>(wCustumerCode); // 前面自定义了Code,对应着下图中 事件ID 20
|
||
|
||
hEventSource = RegisterEventSource(nullptr, WG_TUNNEL_SVR_NAME);
|
||
|
||
if (nullptr != hEventSource) {
|
||
|
||
LPCTSTR lpszStrings[2] = {
|
||
WG_TUNNEL_SVR_NAME,
|
||
szMsg}; //要写入日志的信息有两行,分别是 服务名,和前面给出的szMsg,对应着下图“以下是包含在事件中的信息”
|
||
|
||
ReportEvent(hEventSource, // event log handle
|
||
wErrorType, // event type
|
||
0, // event category
|
||
dwEventIdentifer, // event identifier
|
||
nullptr, // no security identifier
|
||
2, // size of lpszStrings array
|
||
0, // no binary data
|
||
lpszStrings, // array of strings
|
||
nullptr); // no binary data
|
||
DeregisterEventSource(hEventSource);
|
||
}
|
||
}
|
||
|
||
static HMODULE InitializeTunnelLibrary() {
|
||
const HMODULE tunnel = LoadLibraryExW(L"tunnel.dll",
|
||
nullptr,
|
||
LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||
if (!tunnel) {
|
||
TCHAR tMsg[MAX_PATH * sizeof(TCHAR)];
|
||
StringCbPrintf(tMsg, MAX_PATH * sizeof(TCHAR), TEXT("LoadLibraryExW Error: %d\n"), GetLastError());
|
||
LogToSystemEventLog(EVENTLOG_ERROR_TYPE, 0x01, tMsg);
|
||
return nullptr;
|
||
}
|
||
|
||
#define X(Name) ((*(FARPROC *)&(Name) = GetProcAddress(tunnel, #Name)) == nullptr)
|
||
if (X(WireGuardTunnelService))
|
||
#undef X
|
||
{
|
||
const DWORD LastError = GetLastError();
|
||
FreeLibrary(tunnel);
|
||
SetLastError(LastError);
|
||
return nullptr;
|
||
}
|
||
return tunnel;
|
||
}
|
||
|
||
int _tmain(int wargc, _TCHAR *wargv[]) {
|
||
TCHAR tMsg[MAX_PATH] = {};
|
||
|
||
if (wargc == 3 && !wcscmp(wargv[1], L"/service")) {
|
||
BOOL ret;
|
||
const HMODULE hModule = InitializeTunnelLibrary();
|
||
|
||
if (!hModule || !WireGuardTunnelService) {
|
||
StringCbPrintf(tMsg, MAX_PATH, TEXT("Init WireGuardTunnelService Service Error: %d\n"), GetLastError());
|
||
LogToSystemEventLog(EVENTLOG_ERROR_TYPE, 0x01, tMsg);
|
||
return -1;
|
||
}
|
||
|
||
ret = WireGuardTunnelService(wargv[2]);
|
||
|
||
if (ret) {
|
||
StringCbPrintf(tMsg, MAX_PATH, TEXT("Start WireGuardTunnelService Service Successed\n"));
|
||
LogToSystemEventLog(EVENTLOG_INFORMATION_TYPE, 0x00, tMsg);
|
||
} else {
|
||
StringCbPrintf(tMsg, MAX_PATH, TEXT("Start WireGuardTunnelService Service failed: %d\n"), GetLastError());
|
||
LogToSystemEventLog(EVENTLOG_ERROR_TYPE, 0x02, tMsg);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
|
||
// 调试程序: F5 或调试 >“开始调试”菜单
|
||
|
||
// 入门使用技巧:
|
||
// 1. 使用解决方案资源管理器窗口添加/管理文件
|
||
// 2. 使用团队资源管理器窗口连接到源代码管理
|
||
// 3. 使用输出窗口查看生成输出和其他消息
|
||
// 4. 使用错误列表窗口查看错误
|
||
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
|
||
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
|