dragonmoonlight/app/vpn/wintun.h

140 lines
5.6 KiB
C++

// wintun.h - Dynamic-loading wrapper for the Wintun kernel TUN driver.
//
// Wintun is distributed as wintun.dll and loaded at runtime via LoadLibraryEx.
// All API functions are resolved via GetProcAddress.
//
// Reference: https://git.zx2c4.com/wintun
// License : Wintun is (C) WireGuard LLC; the header bindings here are MIT.
//
// Usage:
// WintunLib wt;
// if (!wt.load()) { /* wintun.dll not found */ }
// WINTUN_ADAPTER_HANDLE adp = wt.CreateAdapter(L"DragonMoonlight", L"WireGuard", nullptr);
// ...
// wt.CloseAdapter(adp);
// wt.unload();
#pragma once
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <stdint.h>
// Wintun opaque types
typedef void *WINTUN_ADAPTER_HANDLE;
typedef void *WINTUN_SESSION_HANDLE;
// Wintun function pointer types
typedef WINTUN_ADAPTER_HANDLE(WINAPI *WINTUN_CREATE_ADAPTER_FUNC)(
LPCWSTR Name, LPCWSTR TunnelType, const GUID *RequestedGUID);
typedef WINTUN_ADAPTER_HANDLE(WINAPI *WINTUN_OPEN_ADAPTER_FUNC)(LPCWSTR Name);
typedef void(WINAPI *WINTUN_CLOSE_ADAPTER_FUNC)(WINTUN_ADAPTER_HANDLE Adapter);
typedef BOOL(WINAPI *WINTUN_DELETE_DRIVER_FUNC)(void);
typedef void(WINAPI *WINTUN_GET_ADAPTER_LUID_FUNC)(WINTUN_ADAPTER_HANDLE Adapter,
NET_LUID *Luid);
typedef DWORD(WINAPI *WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC)(void);
typedef WINTUN_SESSION_HANDLE(WINAPI *WINTUN_START_SESSION_FUNC)(
WINTUN_ADAPTER_HANDLE Adapter, DWORD Capacity);
typedef void(WINAPI *WINTUN_END_SESSION_FUNC)(WINTUN_SESSION_HANDLE Session);
typedef HANDLE(WINAPI *WINTUN_GET_READ_WAIT_EVENT_FUNC)(WINTUN_SESSION_HANDLE Session);
typedef BYTE *(WINAPI *WINTUN_RECEIVE_PACKET_FUNC)(WINTUN_SESSION_HANDLE Session,
DWORD *PacketSize);
typedef void(WINAPI *WINTUN_RELEASE_RECEIVE_PACKET_FUNC)(WINTUN_SESSION_HANDLE Session,
const BYTE *Packet);
typedef BYTE *(WINAPI *WINTUN_ALLOC_SEND_PACKET_FUNC)(WINTUN_SESSION_HANDLE Session,
DWORD PacketSize);
typedef void(WINAPI *WINTUN_SEND_PACKET_FUNC)(WINTUN_SESSION_HANDLE Session,
const BYTE *Packet);
// WintunLib - RAII loader
class WintunLib {
public:
WINTUN_CREATE_ADAPTER_FUNC CreateAdapter = nullptr;
WINTUN_OPEN_ADAPTER_FUNC OpenAdapter = nullptr;
WINTUN_CLOSE_ADAPTER_FUNC CloseAdapter = nullptr;
WINTUN_DELETE_DRIVER_FUNC DeleteDriver = nullptr;
WINTUN_GET_ADAPTER_LUID_FUNC GetAdapterLUID = nullptr;
WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC GetRunningDriverVersion = nullptr;
WINTUN_START_SESSION_FUNC StartSession = nullptr;
WINTUN_END_SESSION_FUNC EndSession = nullptr;
WINTUN_GET_READ_WAIT_EVENT_FUNC GetReadWaitEvent = nullptr;
WINTUN_RECEIVE_PACKET_FUNC ReceivePacket = nullptr;
WINTUN_RELEASE_RECEIVE_PACKET_FUNC ReleaseReceivePacket = nullptr;
WINTUN_ALLOC_SEND_PACKET_FUNC AllocateSendPacket = nullptr;
WINTUN_SEND_PACKET_FUNC SendPacket = nullptr;
WintunLib() = default;
~WintunLib() { unload(); }
WintunLib(const WintunLib &) = delete;
WintunLib &operator=(const WintunLib &) = delete;
bool load() {
if (m_module) return true;
m_module = LoadLibraryExW(L"wintun.dll", nullptr,
LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!m_module) return false;
#define WINTUN_RESOLVE(MEMBER, NAME) \
MEMBER = reinterpret_cast<decltype(MEMBER)>(GetProcAddress(m_module, #NAME)); \
if (!MEMBER) { unload(); return false; }
WINTUN_RESOLVE(CreateAdapter, WintunCreateAdapter)
WINTUN_RESOLVE(OpenAdapter, WintunOpenAdapter)
WINTUN_RESOLVE(CloseAdapter, WintunCloseAdapter)
WINTUN_RESOLVE(DeleteDriver, WintunDeleteDriver)
WINTUN_RESOLVE(GetAdapterLUID, WintunGetAdapterLUID)
WINTUN_RESOLVE(GetRunningDriverVersion, WintunGetRunningDriverVersion)
WINTUN_RESOLVE(StartSession, WintunStartSession)
WINTUN_RESOLVE(EndSession, WintunEndSession)
WINTUN_RESOLVE(GetReadWaitEvent, WintunGetReadWaitEvent)
WINTUN_RESOLVE(ReceivePacket, WintunReceivePacket)
WINTUN_RESOLVE(ReleaseReceivePacket, WintunReleaseReceivePacket)
WINTUN_RESOLVE(AllocateSendPacket, WintunAllocateSendPacket)
WINTUN_RESOLVE(SendPacket, WintunSendPacket)
#undef WINTUN_RESOLVE
return true;
}
bool isLoaded() const { return m_module != nullptr; }
void unload() {
if (m_module) { FreeLibrary(m_module); m_module = nullptr; }
CreateAdapter = nullptr;
OpenAdapter = nullptr;
CloseAdapter = nullptr;
DeleteDriver = nullptr;
GetAdapterLUID = nullptr;
GetRunningDriverVersion = nullptr;
StartSession = nullptr;
EndSession = nullptr;
GetReadWaitEvent = nullptr;
ReceivePacket = nullptr;
ReleaseReceivePacket = nullptr;
AllocateSendPacket = nullptr;
SendPacket = nullptr;
}
private:
HMODULE m_module = nullptr;
};