2020-07-24 09:39:02 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0
|
|
|
|
*
|
|
|
|
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
|
|
|
|
*/
|
|
|
|
|
2020-10-31 11:55:26 +01:00
|
|
|
#include "adapter.h"
|
|
|
|
#include "logger.h"
|
2020-10-31 15:09:47 +01:00
|
|
|
#include "session.h"
|
2020-10-31 11:55:26 +01:00
|
|
|
#include "wintun.h"
|
|
|
|
|
|
|
|
#include <Windows.h>
|
2020-10-31 14:45:34 +01:00
|
|
|
#include <cfgmgr32.h>
|
|
|
|
#include <objbase.h>
|
2020-10-31 15:09:47 +01:00
|
|
|
#include <assert.h>
|
2020-07-24 09:39:02 +02:00
|
|
|
|
2020-10-19 22:23:09 +02:00
|
|
|
#define EXPORT comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
|
|
|
|
|
2020-10-31 15:09:47 +01:00
|
|
|
#if defined(ACCEPT_WOW64) || defined(_DEBUG)
|
|
|
|
|
|
|
|
static
|
|
|
|
#ifndef _DEBUG
|
|
|
|
const
|
|
|
|
#endif
|
|
|
|
BOOL WriteToConsole = FALSE;
|
2020-10-19 22:23:09 +02:00
|
|
|
|
|
|
|
static DWORD
|
|
|
|
WriteFormatted(_In_ DWORD StdHandle, _In_z_ const WCHAR *Template, ...)
|
|
|
|
{
|
|
|
|
WCHAR *FormattedMessage = NULL;
|
|
|
|
DWORD SizeWritten;
|
|
|
|
va_list Arguments;
|
|
|
|
va_start(Arguments, Template);
|
2020-10-31 15:09:47 +01:00
|
|
|
DWORD Len = sizeof(WCHAR) * FormatMessageW(
|
|
|
|
FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
|
|
|
Template,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
(void *)&FormattedMessage,
|
|
|
|
0,
|
|
|
|
&Arguments);
|
|
|
|
if (WriteToConsole)
|
|
|
|
WriteConsoleW(GetStdHandle(StdHandle), FormattedMessage, Len, &SizeWritten, NULL);
|
|
|
|
else
|
|
|
|
WriteFile(GetStdHandle(StdHandle), FormattedMessage, Len, &SizeWritten, NULL);
|
2020-10-19 22:23:09 +02:00
|
|
|
LocalFree(FormattedMessage);
|
|
|
|
va_end(Arguments);
|
|
|
|
return SizeWritten / sizeof(WCHAR);
|
|
|
|
}
|
2020-07-24 09:39:02 +02:00
|
|
|
|
2020-10-16 14:17:22 +02:00
|
|
|
static BOOL CALLBACK
|
2020-10-31 08:35:39 +01:00
|
|
|
ConsoleLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ const WCHAR *LogLine)
|
2020-10-15 15:23:23 +02:00
|
|
|
{
|
|
|
|
const WCHAR *Template;
|
|
|
|
switch (Level)
|
|
|
|
{
|
|
|
|
case WINTUN_LOG_INFO:
|
2020-10-19 22:23:09 +02:00
|
|
|
Template = L"[+] %1\n";
|
2020-10-15 15:23:23 +02:00
|
|
|
break;
|
|
|
|
case WINTUN_LOG_WARN:
|
2020-10-19 22:23:09 +02:00
|
|
|
Template = L"[-] %1\n";
|
2020-10-15 15:23:23 +02:00
|
|
|
break;
|
|
|
|
case WINTUN_LOG_ERR:
|
2020-10-19 22:23:09 +02:00
|
|
|
Template = L"[!] %1\n";
|
2020-10-15 15:23:23 +02:00
|
|
|
break;
|
|
|
|
default:
|
2020-10-16 14:17:22 +02:00
|
|
|
return FALSE;
|
2020-10-15 15:23:23 +02:00
|
|
|
}
|
2020-10-19 22:23:09 +02:00
|
|
|
WriteFormatted(STD_ERROR_HANDLE, Template, LogLine);
|
2020-10-16 14:17:22 +02:00
|
|
|
return TRUE;
|
2020-10-15 15:23:23 +02:00
|
|
|
}
|
|
|
|
|
2020-10-16 13:26:04 +02:00
|
|
|
static int Argc;
|
|
|
|
static WCHAR **Argv;
|
|
|
|
|
2020-10-19 22:23:09 +02:00
|
|
|
static void
|
|
|
|
Init(void)
|
2020-10-15 15:23:23 +02:00
|
|
|
{
|
|
|
|
WintunSetLogger(ConsoleLogger);
|
2020-10-16 13:26:04 +02:00
|
|
|
Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);
|
2020-10-15 15:23:23 +02:00
|
|
|
}
|
|
|
|
|
2020-10-19 22:23:09 +02:00
|
|
|
static void
|
|
|
|
Done(void)
|
2020-10-15 15:23:23 +02:00
|
|
|
{
|
2020-10-16 13:26:04 +02:00
|
|
|
LocalFree(Argv);
|
2020-10-15 15:23:23 +02:00
|
|
|
}
|
|
|
|
|
2020-10-19 22:23:09 +02:00
|
|
|
VOID __stdcall CreateAdapter(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
|
2020-07-24 09:39:02 +02:00
|
|
|
{
|
2020-10-19 22:23:09 +02:00
|
|
|
# pragma EXPORT
|
2020-07-24 09:39:02 +02:00
|
|
|
UNREFERENCED_PARAMETER(hwnd);
|
|
|
|
UNREFERENCED_PARAMETER(hinst);
|
|
|
|
UNREFERENCED_PARAMETER(lpszCmdLine);
|
2020-10-16 13:26:04 +02:00
|
|
|
UNREFERENCED_PARAMETER(nCmdShow);
|
2020-07-24 09:39:02 +02:00
|
|
|
|
2020-10-16 13:26:04 +02:00
|
|
|
Init();
|
2020-07-24 09:39:02 +02:00
|
|
|
if (Argc < 4)
|
2020-10-16 13:26:04 +02:00
|
|
|
goto cleanup;
|
2020-10-31 08:53:32 +01:00
|
|
|
if (wcslen(Argv[2]) >= WINTUN_MAX_POOL)
|
2020-10-16 13:26:04 +02:00
|
|
|
goto cleanup;
|
2020-07-24 09:39:02 +02:00
|
|
|
if (wcslen(Argv[3]) >= MAX_ADAPTER_NAME)
|
2020-10-16 13:26:04 +02:00
|
|
|
goto cleanup;
|
2020-07-24 09:39:02 +02:00
|
|
|
GUID RequestedGUID;
|
|
|
|
if (Argc > 4 && FAILED(CLSIDFromString(Argv[4], &RequestedGUID)))
|
2020-10-16 13:26:04 +02:00
|
|
|
goto cleanup;
|
|
|
|
|
2020-07-24 09:39:02 +02:00
|
|
|
WINTUN_ADAPTER *Adapter;
|
|
|
|
BOOL RebootRequired = FALSE;
|
|
|
|
DWORD Result = WintunCreateAdapter(Argv[2], Argv[3], Argc > 4 ? &RequestedGUID : NULL, &Adapter, &RebootRequired);
|
2020-10-19 22:23:09 +02:00
|
|
|
WCHAR GuidStr[MAX_GUID_STRING_LEN];
|
|
|
|
WriteFormatted(
|
|
|
|
STD_OUTPUT_HANDLE,
|
|
|
|
L"%1!X! %2!.*s! %3!X!",
|
|
|
|
Result,
|
|
|
|
StringFromGUID2(Result == ERROR_SUCCESS ? &Adapter->CfgInstanceID : &GUID_NULL, GuidStr, _countof(GuidStr)),
|
|
|
|
GuidStr,
|
|
|
|
RebootRequired);
|
2020-07-24 09:39:02 +02:00
|
|
|
WintunFreeAdapter(Adapter);
|
2020-10-16 13:26:04 +02:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
Done();
|
2020-07-24 09:39:02 +02:00
|
|
|
}
|
|
|
|
|
2020-10-19 22:23:09 +02:00
|
|
|
VOID __stdcall DeleteAdapter(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
|
2020-07-24 09:39:02 +02:00
|
|
|
{
|
2020-10-19 22:23:09 +02:00
|
|
|
# pragma EXPORT
|
2020-07-24 09:39:02 +02:00
|
|
|
UNREFERENCED_PARAMETER(hwnd);
|
|
|
|
UNREFERENCED_PARAMETER(hinst);
|
|
|
|
UNREFERENCED_PARAMETER(lpszCmdLine);
|
2020-10-16 13:26:04 +02:00
|
|
|
UNREFERENCED_PARAMETER(nCmdShow);
|
2020-07-24 09:39:02 +02:00
|
|
|
|
2020-10-16 13:26:04 +02:00
|
|
|
Init();
|
2020-07-24 09:39:02 +02:00
|
|
|
if (Argc < 3)
|
2020-10-16 13:26:04 +02:00
|
|
|
goto cleanup;
|
2020-07-24 09:39:02 +02:00
|
|
|
|
|
|
|
WINTUN_ADAPTER Adapter = { 0 };
|
2020-10-30 14:34:40 +01:00
|
|
|
BOOL ForceCloseSessions = wcstoul(Argv[2], NULL, 10);
|
|
|
|
if (FAILED(CLSIDFromString(Argv[3], &Adapter.CfgInstanceID)))
|
2020-10-16 13:26:04 +02:00
|
|
|
goto cleanup;
|
2020-07-24 09:39:02 +02:00
|
|
|
BOOL RebootRequired = FALSE;
|
2020-10-31 08:53:32 +01:00
|
|
|
WriteFormatted(
|
|
|
|
STD_OUTPUT_HANDLE,
|
|
|
|
L"%1!X! %2!X!",
|
|
|
|
WintunDeleteAdapter(&Adapter, ForceCloseSessions, &RebootRequired),
|
|
|
|
RebootRequired);
|
2020-07-24 09:39:02 +02:00
|
|
|
|
2020-10-16 13:26:04 +02:00
|
|
|
cleanup:
|
|
|
|
Done();
|
2020-07-24 09:39:02 +02:00
|
|
|
}
|
|
|
|
|
2020-10-31 15:09:47 +01:00
|
|
|
#ifdef _DEBUG
|
|
|
|
VOID __stdcall DoThingsForDebugging(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
|
|
|
|
{
|
|
|
|
# pragma EXPORT
|
|
|
|
UNREFERENCED_PARAMETER(hwnd);
|
|
|
|
UNREFERENCED_PARAMETER(hinst);
|
|
|
|
UNREFERENCED_PARAMETER(lpszCmdLine);
|
|
|
|
UNREFERENCED_PARAMETER(nCmdShow);
|
|
|
|
|
|
|
|
AllocConsole();
|
|
|
|
WriteToConsole = TRUE;
|
|
|
|
Init();
|
|
|
|
GUID TestGuid = {
|
|
|
|
0xdeadbabe,
|
|
|
|
0xcafe,
|
|
|
|
0xbeef,
|
|
|
|
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }
|
|
|
|
};
|
|
|
|
WINTUN_ADAPTER *Adapter;
|
|
|
|
BOOL RebootRequired = FALSE;
|
|
|
|
assert(WintunCreateAdapter(L"Wintun", L"Test", &TestGuid, &Adapter, &RebootRequired) == ERROR_SUCCESS);
|
|
|
|
assert(!RebootRequired);
|
|
|
|
TUN_SESSION *Session;
|
|
|
|
HANDLE ReadWait;
|
|
|
|
assert(WintunStartSession(Adapter, WINTUN_MIN_RING_CAPACITY, &Session, &ReadWait) == ERROR_SUCCESS);
|
|
|
|
WintunEndSession(Session);
|
|
|
|
assert(WintunDeleteAdapter(Adapter, TRUE, &RebootRequired) == ERROR_SUCCESS);
|
|
|
|
assert(!RebootRequired);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-07-24 09:39:02 +02:00
|
|
|
#endif
|