example: rewrite and replace api's debug rundll32 functionality
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
		
							parent
							
								
									0d7b9c7319
								
							
						
					
					
						commit
						9a937c7a49
					
				@ -101,11 +101,6 @@
 | 
				
			|||||||
    <RunCodeAnalysis>true</RunCodeAnalysis>
 | 
					    <RunCodeAnalysis>true</RunCodeAnalysis>
 | 
				
			||||||
    <IgnoreImportLibrary>true</IgnoreImportLibrary>
 | 
					    <IgnoreImportLibrary>true</IgnoreImportLibrary>
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
 | 
					 | 
				
			||||||
    <LocalDebuggerCommand>rundll32.exe</LocalDebuggerCommand>
 | 
					 | 
				
			||||||
    <LocalDebuggerCommandArguments>$(OutDir)$(TargetName)$(TargetExt),DoThingsForDebugging</LocalDebuggerCommandArguments>
 | 
					 | 
				
			||||||
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
 | 
					 | 
				
			||||||
  </PropertyGroup>
 | 
					 | 
				
			||||||
  <ItemDefinitionGroup>
 | 
					  <ItemDefinitionGroup>
 | 
				
			||||||
    <ClCompile>
 | 
					    <ClCompile>
 | 
				
			||||||
      <PreprocessorDefinitions>_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
					      <PreprocessorDefinitions>_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
				
			||||||
@ -171,7 +166,6 @@ lib.exe /def:nci.def /out:"$(IntDir)nci.lib" /machine:$(PlatformTarget) /nologo
 | 
				
			|||||||
    <ClInclude Include="ntldr.h" />
 | 
					    <ClInclude Include="ntldr.h" />
 | 
				
			||||||
    <ClInclude Include="registry.h" />
 | 
					    <ClInclude Include="registry.h" />
 | 
				
			||||||
    <ClInclude Include="resource.h" />
 | 
					    <ClInclude Include="resource.h" />
 | 
				
			||||||
    <ClInclude Include="session.h" />
 | 
					 | 
				
			||||||
    <ClInclude Include="wintun.h" />
 | 
					    <ClInclude Include="wintun.h" />
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
				
			|||||||
@ -58,9 +58,6 @@
 | 
				
			|||||||
    <ClInclude Include="entry.h">
 | 
					    <ClInclude Include="entry.h">
 | 
				
			||||||
      <Filter>Header Files</Filter>
 | 
					      <Filter>Header Files</Filter>
 | 
				
			||||||
    </ClInclude>
 | 
					    </ClInclude>
 | 
				
			||||||
    <ClInclude Include="session.h">
 | 
					 | 
				
			||||||
      <Filter>Header Files</Filter>
 | 
					 | 
				
			||||||
    </ClInclude>
 | 
					 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
    <ClCompile Include="namespace.c">
 | 
					    <ClCompile Include="namespace.c">
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "adapter.h"
 | 
					#include "adapter.h"
 | 
				
			||||||
#include "logger.h"
 | 
					#include "logger.h"
 | 
				
			||||||
#include "session.h"
 | 
					 | 
				
			||||||
#include "wintun.h"
 | 
					#include "wintun.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <Windows.h>
 | 
					#include <Windows.h>
 | 
				
			||||||
@ -17,12 +16,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if defined(ACCEPT_WOW64) || defined(_DEBUG)
 | 
					#if defined(ACCEPT_WOW64) || defined(_DEBUG)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static
 | 
					 | 
				
			||||||
#ifndef _DEBUG
 | 
					 | 
				
			||||||
const
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
BOOL WriteToConsole = FALSE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static DWORD
 | 
					static DWORD
 | 
				
			||||||
WriteFormatted(_In_ DWORD StdHandle, _In_z_ const WCHAR *Template, ...)
 | 
					WriteFormatted(_In_ DWORD StdHandle, _In_z_ const WCHAR *Template, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -38,9 +31,6 @@ WriteFormatted(_In_ DWORD StdHandle, _In_z_ const WCHAR *Template, ...)
 | 
				
			|||||||
        (void *)&FormattedMessage,
 | 
					        (void *)&FormattedMessage,
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
        &Arguments);
 | 
					        &Arguments);
 | 
				
			||||||
    if (WriteToConsole)
 | 
					 | 
				
			||||||
        WriteConsoleW(GetStdHandle(StdHandle), FormattedMessage, Len, &SizeWritten, NULL);
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
    WriteFile(GetStdHandle(StdHandle), FormattedMessage, Len * sizeof(WCHAR), &SizeWritten, NULL);
 | 
					    WriteFile(GetStdHandle(StdHandle), FormattedMessage, Len * sizeof(WCHAR), &SizeWritten, NULL);
 | 
				
			||||||
    LocalFree(FormattedMessage);
 | 
					    LocalFree(FormattedMessage);
 | 
				
			||||||
    va_end(Arguments);
 | 
					    va_end(Arguments);
 | 
				
			||||||
@ -158,30 +148,4 @@ VOID __stdcall DeleteDriver(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int n
 | 
				
			|||||||
    Done();
 | 
					    Done();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#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;
 | 
					 | 
				
			||||||
    assert(WintunCreateAdapter(L"Wintun", L"Test", &TestGuid, &Adapter, &RebootRequired) == ERROR_SUCCESS);
 | 
					 | 
				
			||||||
    assert(!RebootRequired);
 | 
					 | 
				
			||||||
    TUN_SESSION *Session;
 | 
					 | 
				
			||||||
    assert(WintunStartSession(Adapter, WINTUN_MIN_RING_CAPACITY, &Session) == ERROR_SUCCESS);
 | 
					 | 
				
			||||||
    WintunEndSession(Session);
 | 
					 | 
				
			||||||
    assert(WintunDeleteAdapter(Adapter, TRUE, &RebootRequired) == ERROR_SUCCESS);
 | 
					 | 
				
			||||||
    assert(!RebootRequired);
 | 
					 | 
				
			||||||
    system("pause");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,6 @@
 | 
				
			|||||||
#include "elevate.h"
 | 
					#include "elevate.h"
 | 
				
			||||||
#include "entry.h"
 | 
					#include "entry.h"
 | 
				
			||||||
#include "logger.h"
 | 
					#include "logger.h"
 | 
				
			||||||
#include "session.h"
 | 
					 | 
				
			||||||
#include "wintun.h"
 | 
					#include "wintun.h"
 | 
				
			||||||
#include <Windows.h>
 | 
					#include <Windows.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,59 +0,0 @@
 | 
				
			|||||||
/* SPDX-License-Identifier: GPL-2.0
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "wintun.h"
 | 
					 | 
				
			||||||
#include <Windows.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct _TUN_SESSION TUN_SESSION;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @copydoc WINTUN_START_SESSION_FUNC
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
WINTUN_STATUS WINAPI
 | 
					 | 
				
			||||||
WintunStartSession(
 | 
					 | 
				
			||||||
    _In_ const WINTUN_ADAPTER *Adapter,
 | 
					 | 
				
			||||||
    _In_ DWORD Capacity,
 | 
					 | 
				
			||||||
    _Out_ TUN_SESSION **Session);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @copydoc WINTUN_END_SESSION_FUNC
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void WINAPI
 | 
					 | 
				
			||||||
WintunEndSession(_In_ TUN_SESSION *Session);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @copydoc WINTUN_GET_READ_WAIT_EVENT_FUNC
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
HANDLE WINAPI
 | 
					 | 
				
			||||||
WintunGetReadWaitEvent(_In_ TUN_SESSION *Session);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @copydoc WINTUN_RECEIVE_PACKET_FUNC
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
WINTUN_STATUS WINAPI
 | 
					 | 
				
			||||||
WintunReceivePacket(_In_ TUN_SESSION *Session, _Out_bytecapcount_(*PacketSize) BYTE **Packet, _Out_ DWORD *PacketSize);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @copydoc WINTUN_RECEIVE_RELEASE_FUNC
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void WINAPI
 | 
					 | 
				
			||||||
WintunReceiveRelease(_In_ TUN_SESSION *Session, _In_ const BYTE *Packet);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @copydoc WINTUN_ALLOCATE_SEND_PACKET
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
WINTUN_STATUS WINAPI
 | 
					 | 
				
			||||||
WintunAllocateSendPacket(
 | 
					 | 
				
			||||||
    _In_ TUN_SESSION *Session,
 | 
					 | 
				
			||||||
    _In_ DWORD PacketSize,
 | 
					 | 
				
			||||||
    _Out_bytecapcount_(PacketSize) BYTE **Packet);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @copydoc WINTUN_SEND_PACKET
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void WINAPI
 | 
					 | 
				
			||||||
WintunSendPacket(_In_ TUN_SESSION *Session, _In_ const BYTE *Packet);
 | 
					 | 
				
			||||||
@ -3,16 +3,31 @@
 | 
				
			|||||||
 * Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
 | 
					 * Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../api/wintun.h"
 | 
					#include <winsock2.h>
 | 
				
			||||||
 | 
					#include <Windows.h>
 | 
				
			||||||
 | 
					#include <ws2ipdef.h>
 | 
				
			||||||
 | 
					#include <iphlpapi.h>
 | 
				
			||||||
 | 
					#include <ip2string.h>
 | 
				
			||||||
#include <stdarg.h>
 | 
					#include <stdarg.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "wintun.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static WINTUN_GET_VERSION_FUNC WintunGetVersion;
 | 
					 | 
				
			||||||
static WINTUN_SET_LOGGER_FUNC WintunSetLogger;
 | 
					 | 
				
			||||||
static WINTUN_CREATE_ADAPTER_FUNC WintunCreateAdapter;
 | 
					static WINTUN_CREATE_ADAPTER_FUNC WintunCreateAdapter;
 | 
				
			||||||
static WINTUN_DELETE_ADAPTER_FUNC WintunDeleteAdapter;
 | 
					static WINTUN_DELETE_ADAPTER_FUNC WintunDeleteAdapter;
 | 
				
			||||||
 | 
					static WINTUN_DELETE_DRIVER_FUNC WintunDeleteDriver;
 | 
				
			||||||
 | 
					static WINTUN_ENUM_ADAPTERS_FUNC WintunEnumAdapters;
 | 
				
			||||||
 | 
					static WINTUN_FREE_ADAPTER_FUNC WintunFreeAdapter;
 | 
				
			||||||
 | 
					static WINTUN_GET_ADAPTER_FUNC WintunGetAdapter;
 | 
				
			||||||
 | 
					static WINTUN_GET_ADAPTER_DEVICE_OBJECT_FUNC WintunGetAdapterDeviceObject;
 | 
				
			||||||
 | 
					static WINTUN_GET_ADAPTER_GUID_FUNC WintunGetAdapterGUID;
 | 
				
			||||||
 | 
					static WINTUN_GET_ADAPTER_LUID_FUNC WintunGetAdapterLUID;
 | 
				
			||||||
 | 
					static WINTUN_GET_ADAPTER_NAME_FUNC WintunGetAdapterName;
 | 
				
			||||||
 | 
					static WINTUN_SET_ADAPTER_NAME_FUNC WintunSetAdapterName;
 | 
				
			||||||
 | 
					static WINTUN_GET_VERSION_FUNC WintunGetVersion;
 | 
				
			||||||
 | 
					static WINTUN_SET_LOGGER_FUNC WintunSetLogger;
 | 
				
			||||||
static WINTUN_START_SESSION_FUNC WintunStartSession;
 | 
					static WINTUN_START_SESSION_FUNC WintunStartSession;
 | 
				
			||||||
static WINTUN_END_SESSION_FUNC WintunEndSession;
 | 
					static WINTUN_END_SESSION_FUNC WintunEndSession;
 | 
				
			||||||
 | 
					static WINTUN_GET_READ_WAIT_EVENT_FUNC WintunGetReadWaitEvent;
 | 
				
			||||||
static WINTUN_RECEIVE_PACKET_FUNC WintunReceivePacket;
 | 
					static WINTUN_RECEIVE_PACKET_FUNC WintunReceivePacket;
 | 
				
			||||||
static WINTUN_RECEIVE_RELEASE_FUNC WintunReceiveRelease;
 | 
					static WINTUN_RECEIVE_RELEASE_FUNC WintunReceiveRelease;
 | 
				
			||||||
static WINTUN_ALLOCATE_SEND_PACKET_FUNC WintunAllocateSendPacket;
 | 
					static WINTUN_ALLOCATE_SEND_PACKET_FUNC WintunAllocateSendPacket;
 | 
				
			||||||
@ -59,9 +74,8 @@ ConsoleLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ const WCHAR *LogLine)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DWORD
 | 
					static DWORD
 | 
				
			||||||
LogLastError(_In_z_ const WCHAR *Prefix)
 | 
					LogError(_In_z_ const WCHAR *Prefix, _In_ DWORD Error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DWORD Error = GetLastError();
 | 
					 | 
				
			||||||
    WCHAR *SystemMessage = NULL, *FormattedMessage = NULL;
 | 
					    WCHAR *SystemMessage = NULL, *FormattedMessage = NULL;
 | 
				
			||||||
    FormatMessageW(
 | 
					    FormatMessageW(
 | 
				
			||||||
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK,
 | 
					        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK,
 | 
				
			||||||
@ -84,7 +98,6 @@ LogLastError(_In_z_ const WCHAR *Prefix)
 | 
				
			|||||||
        ConsoleLogger(WINTUN_LOG_ERR, FormattedMessage);
 | 
					        ConsoleLogger(WINTUN_LOG_ERR, FormattedMessage);
 | 
				
			||||||
    LocalFree(FormattedMessage);
 | 
					    LocalFree(FormattedMessage);
 | 
				
			||||||
    LocalFree(SystemMessage);
 | 
					    LocalFree(SystemMessage);
 | 
				
			||||||
    SetLastError(Error);
 | 
					 | 
				
			||||||
    return Error;
 | 
					    return Error;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -100,7 +113,7 @@ Log(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ const WCHAR *Format, ...)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static BOOL WINAPI
 | 
					static BOOL WINAPI
 | 
				
			||||||
CtrlHandler(DWORD CtrlType)
 | 
					CtrlHandler(_In_ DWORD CtrlType)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    switch (CtrlType)
 | 
					    switch (CtrlType)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -109,6 +122,7 @@ CtrlHandler(DWORD CtrlType)
 | 
				
			|||||||
    case CTRL_CLOSE_EVENT:
 | 
					    case CTRL_CLOSE_EVENT:
 | 
				
			||||||
    case CTRL_LOGOFF_EVENT:
 | 
					    case CTRL_LOGOFF_EVENT:
 | 
				
			||||||
    case CTRL_SHUTDOWN_EVENT:
 | 
					    case CTRL_SHUTDOWN_EVENT:
 | 
				
			||||||
 | 
					        Log(WINTUN_LOG_INFO, L"Cleaning up and shutting down...");
 | 
				
			||||||
        HaveQuit = TRUE;
 | 
					        HaveQuit = TRUE;
 | 
				
			||||||
        SetEvent(QuitEvent);
 | 
					        SetEvent(QuitEvent);
 | 
				
			||||||
        return TRUE;
 | 
					        return TRUE;
 | 
				
			||||||
@ -116,143 +130,249 @@ CtrlHandler(DWORD CtrlType)
 | 
				
			|||||||
    return FALSE;
 | 
					    return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					PrintPacket(_In_ const BYTE *Packet, _In_ DWORD PacketSize)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (PacketSize < 20)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Log(WINTUN_LOG_INFO, L"Received packet without room for an IP header");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    BYTE IpVersion = Packet[0] >> 4, Proto;
 | 
				
			||||||
 | 
					    WCHAR Src[46], Dst[46];
 | 
				
			||||||
 | 
					    if (IpVersion == 4)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        RtlIpv4AddressToStringW((struct in_addr *)&Packet[12], Src);
 | 
				
			||||||
 | 
					        RtlIpv4AddressToStringW((struct in_addr *)&Packet[16], Dst);
 | 
				
			||||||
 | 
					        Proto = Packet[9];
 | 
				
			||||||
 | 
					        Packet += 20, PacketSize -= 20;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (IpVersion == 6 && PacketSize < 40)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Log(WINTUN_LOG_INFO, L"Received packet without room for an IP header");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (IpVersion == 6)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        RtlIpv6AddressToStringW((struct in6_addr *)&Packet[8], Src);
 | 
				
			||||||
 | 
					        RtlIpv6AddressToStringW((struct in6_addr *)&Packet[24], Dst);
 | 
				
			||||||
 | 
					        Proto = Packet[6];
 | 
				
			||||||
 | 
					        Packet += 40, PacketSize -= 40;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Log(WINTUN_LOG_INFO, L"Received packet that was not IP");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (Proto == 1 && PacketSize >= 8 && Packet[0] == 0)
 | 
				
			||||||
 | 
					        Log(WINTUN_LOG_INFO, L"Received IPv%d ICMP echo reply from %s to %s", IpVersion, Src, Dst);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        Log(WINTUN_LOG_INFO, L"Received IPv%d proto 0x%x packet from %s to %s", IpVersion, Proto, Src, Dst);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static USHORT
 | 
				
			||||||
 | 
					IPChecksum(BYTE *Buffer, DWORD Len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ULONG Sum = 0;
 | 
				
			||||||
 | 
					    for (; Len > 1; Len -= 2, Buffer += 2)
 | 
				
			||||||
 | 
					        Sum += *(USHORT *)Buffer;
 | 
				
			||||||
 | 
					    if (Len)
 | 
				
			||||||
 | 
					        Sum += *Buffer;
 | 
				
			||||||
 | 
					    Sum = (Sum >> 16) + (Sum & 0xffff);
 | 
				
			||||||
 | 
					    Sum += (Sum >> 16);
 | 
				
			||||||
 | 
					    return (USHORT)(~Sum);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					MakeICMP(_Inout_ BYTE Packet[28])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memset(Packet, 0, 28);
 | 
				
			||||||
 | 
					    Packet[0] = 0x45;
 | 
				
			||||||
 | 
					    *(USHORT *)&Packet[2] = htons(28);
 | 
				
			||||||
 | 
					    Packet[8] = 255;
 | 
				
			||||||
 | 
					    Packet[9] = 1;
 | 
				
			||||||
 | 
					    *(ULONG *)&Packet[12] = htonl((10 << 24) | (6 << 16) | (7 << 8) | (8 << 0)); /* 10.6.7.8 */
 | 
				
			||||||
 | 
					    *(ULONG *)&Packet[16] = htonl((10 << 24) | (6 << 16) | (7 << 8) | (7 << 0)); /* 10.6.7.7 */
 | 
				
			||||||
 | 
					    *(USHORT *)&Packet[10] = IPChecksum(Packet, 20);
 | 
				
			||||||
 | 
					    Packet[20] = 8;
 | 
				
			||||||
 | 
					    *(USHORT *)&Packet[22] = IPChecksum(&Packet[20], 8);
 | 
				
			||||||
 | 
					    Log(WINTUN_LOG_INFO, L"Sending IPv4 ICMP echo request to 10.6.7.8 from 10.6.7.7");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DWORD WINAPI
 | 
					static DWORD WINAPI
 | 
				
			||||||
TestAdapter(_Inout_ DWORD_PTR Index)
 | 
					ReceivePackets(_Inout_ DWORD_PTR SessionPtr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* Create adapter. */
 | 
					    WINTUN_SESSION_HANDLE Session = (WINTUN_SESSION_HANDLE)SessionPtr;
 | 
				
			||||||
    WCHAR AdapterName[MAX_ADAPTER_NAME];
 | 
					    HANDLE WaitHandles[] = { WintunGetReadWaitEvent(Session), QuitEvent };
 | 
				
			||||||
    _snwprintf_s(
 | 
					 | 
				
			||||||
        AdapterName,
 | 
					 | 
				
			||||||
        _countof(AdapterName),
 | 
					 | 
				
			||||||
        _TRUNCATE,
 | 
					 | 
				
			||||||
        L"test-%d.%d-%zu",
 | 
					 | 
				
			||||||
        WINTUN_VERSION_MAJ,
 | 
					 | 
				
			||||||
        WINTUN_VERSION_MIN,
 | 
					 | 
				
			||||||
        Index);
 | 
					 | 
				
			||||||
    const GUID AdapterGuid = { 0xeef7ebf,
 | 
					 | 
				
			||||||
                               WINTUN_VERSION_MAJ,
 | 
					 | 
				
			||||||
                               WINTUN_VERSION_MIN,
 | 
					 | 
				
			||||||
                               { (BYTE)Index & 0xff, 0xa, 0x33, 0xbf, 0x5c, 0x8, 0x4a, 0xc6 } };
 | 
					 | 
				
			||||||
    while (!HaveQuit)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        WINTUN_ADAPTER_HANDLE Adapter;
 | 
					 | 
				
			||||||
        BOOL RebootRequired = FALSE;
 | 
					 | 
				
			||||||
        DWORD Result = WintunCreateAdapter(L"Example", AdapterName, &AdapterGuid, &Adapter, &RebootRequired);
 | 
					 | 
				
			||||||
        if (Result != ERROR_SUCCESS)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Log(WINTUN_LOG_ERR, L"%s adapter creation failed.\n", AdapterName);
 | 
					 | 
				
			||||||
            return Result;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DWORDLONG WintunVersion = WintunGetVersion();
 | 
					 | 
				
			||||||
        Log(WINTUN_LOG_INFO,
 | 
					 | 
				
			||||||
            L"%s adapter created (Wintun %d.%d.%d.%d, reboot: %d).\n",
 | 
					 | 
				
			||||||
            AdapterName,
 | 
					 | 
				
			||||||
            (WintunVersion >> 48) & 0xffff,
 | 
					 | 
				
			||||||
            (WintunVersion >> 32) & 0xffff,
 | 
					 | 
				
			||||||
            (WintunVersion >> 16) & 0xffff,
 | 
					 | 
				
			||||||
            (WintunVersion >> 0) & 0xffff,
 | 
					 | 
				
			||||||
            RebootRequired ? 1 : 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        WINTUN_SESSION_HANDLE Session;
 | 
					 | 
				
			||||||
        HANDLE WaitHandles[2] = { NULL, QuitEvent };
 | 
					 | 
				
			||||||
        Result = WintunStartSession(Adapter, 0x100000, &Session, &WaitHandles[0]);
 | 
					 | 
				
			||||||
        if (Result != ERROR_SUCCESS)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Log(WINTUN_LOG_ERR, L"%s session creation failed.\n", AdapterName);
 | 
					 | 
				
			||||||
            goto cleanupAdapter;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    while (!HaveQuit)
 | 
					    while (!HaveQuit)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        BYTE *Packet;
 | 
					        BYTE *Packet;
 | 
				
			||||||
        DWORD PacketSize;
 | 
					        DWORD PacketSize;
 | 
				
			||||||
            Result = WintunReceivePacket(Session, &Packet, &PacketSize);
 | 
					        DWORD Result = WintunReceivePacket(Session, &Packet, &PacketSize);
 | 
				
			||||||
        switch (Result)
 | 
					        switch (Result)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        case ERROR_SUCCESS:
 | 
					        case ERROR_SUCCESS:
 | 
				
			||||||
                // TODO: Process packet.
 | 
					            PrintPacket(Packet, PacketSize);
 | 
				
			||||||
            WintunReceiveRelease(Session, Packet);
 | 
					            WintunReceiveRelease(Session, Packet);
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        case ERROR_NO_MORE_ITEMS:
 | 
					        case ERROR_NO_MORE_ITEMS:
 | 
				
			||||||
            if (WaitForMultipleObjects(_countof(WaitHandles), WaitHandles, FALSE, INFINITE) == WAIT_OBJECT_0)
 | 
					            if (WaitForMultipleObjects(_countof(WaitHandles), WaitHandles, FALSE, INFINITE) == WAIT_OBJECT_0)
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
                goto cleanupSession;
 | 
					            return ERROR_SUCCESS;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            LogError(L"Packet read failed", Result);
 | 
				
			||||||
 | 
					            return Result;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
            Log(WINTUN_LOG_ERR, L"%s packet read failed (Code 0x%08X).\n", AdapterName, Result);
 | 
					 | 
				
			||||||
            goto cleanupSession;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    cleanupSession:
 | 
					 | 
				
			||||||
        WintunEndSession(Session);
 | 
					 | 
				
			||||||
    cleanupAdapter:
 | 
					 | 
				
			||||||
        WintunDeleteAdapter(Adapter, TRUE, &RebootRequired);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ERROR_SUCCESS;
 | 
					    return ERROR_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static DWORD WINAPI
 | 
				
			||||||
 | 
					SendPackets(_Inout_ DWORD_PTR SessionPtr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    WINTUN_SESSION_HANDLE Session = (WINTUN_SESSION_HANDLE)SessionPtr;
 | 
				
			||||||
 | 
					    while (!HaveQuit)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        BYTE *Packet;
 | 
				
			||||||
 | 
					        WintunAllocateSendPacket(Session, 28, &Packet);
 | 
				
			||||||
 | 
					        MakeICMP(Packet);
 | 
				
			||||||
 | 
					        WintunSendPacket(Session, Packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (WaitForSingleObject(QuitEvent, 1000 /* 1 second */))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        case WAIT_ABANDONED:
 | 
				
			||||||
 | 
					        case WAIT_OBJECT_0:
 | 
				
			||||||
 | 
					            return ERROR_SUCCESS;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return ERROR_SUCCESS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static HMODULE
 | 
				
			||||||
 | 
					InitializeWintun(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    HMODULE Wintun =
 | 
				
			||||||
 | 
					        LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
 | 
				
			||||||
 | 
					    if (!Wintun)
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					#define X(Name, Type) ((Name = (Type)GetProcAddress(Wintun, #Name)) == NULL)
 | 
				
			||||||
 | 
					    if (X(WintunCreateAdapter, WINTUN_CREATE_ADAPTER_FUNC) || X(WintunDeleteAdapter, WINTUN_DELETE_ADAPTER_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunDeleteDriver, WINTUN_DELETE_DRIVER_FUNC) || X(WintunEnumAdapters, WINTUN_ENUM_ADAPTERS_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunFreeAdapter, WINTUN_FREE_ADAPTER_FUNC) || X(WintunGetAdapter, WINTUN_GET_ADAPTER_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunGetAdapterDeviceObject, WINTUN_GET_ADAPTER_DEVICE_OBJECT_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunGetAdapterGUID, WINTUN_GET_ADAPTER_GUID_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunGetAdapterLUID, WINTUN_GET_ADAPTER_LUID_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunGetAdapterName, WINTUN_GET_ADAPTER_NAME_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunSetAdapterName, WINTUN_SET_ADAPTER_NAME_FUNC) || X(WintunGetVersion, WINTUN_GET_VERSION_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunSetLogger, WINTUN_SET_LOGGER_FUNC) || X(WintunStartSession, WINTUN_START_SESSION_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunEndSession, WINTUN_END_SESSION_FUNC) || X(WintunGetReadWaitEvent, WINTUN_GET_READ_WAIT_EVENT_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunReceivePacket, WINTUN_RECEIVE_PACKET_FUNC) || X(WintunReceiveRelease, WINTUN_RECEIVE_RELEASE_FUNC) ||
 | 
				
			||||||
 | 
					        X(WintunAllocateSendPacket, WINTUN_ALLOCATE_SEND_PACKET_FUNC) || X(WintunSendPacket, WINTUN_SEND_PACKET_FUNC))
 | 
				
			||||||
 | 
					#undef X
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DWORD Result = GetLastError();
 | 
				
			||||||
 | 
					        FreeLibrary(Wintun);
 | 
				
			||||||
 | 
					        SetLastError(Result);
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    SetLastError(ERROR_SUCCESS);
 | 
				
			||||||
 | 
					    return Wintun;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
main(void)
 | 
					main(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Log(WINTUN_LOG_INFO, L"Wintun Test v%d.%d\n", WINTUN_VERSION_MAJ, WINTUN_VERSION_MIN);
 | 
					    HMODULE Wintun = InitializeWintun();
 | 
				
			||||||
 | 
					 | 
				
			||||||
    HMODULE Wintun =
 | 
					 | 
				
			||||||
        LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
 | 
					 | 
				
			||||||
    if (!Wintun)
 | 
					    if (!Wintun)
 | 
				
			||||||
        return LogLastError(L"Failed to load wintun.dll");
 | 
					        return LogError(L"Failed to initialize Wintun", GetLastError());
 | 
				
			||||||
    DWORD Result;
 | 
					    WintunSetLogger(ConsoleLogger);
 | 
				
			||||||
    if ((WintunGetVersion = (WINTUN_GET_VERSION_FUNC)GetProcAddress(Wintun, "WintunGetVersion")) == NULL ||
 | 
					    Log(WINTUN_LOG_INFO, L"Wintun library loaded");
 | 
				
			||||||
        (WintunSetLogger = (WINTUN_SET_LOGGER_FUNC)GetProcAddress(Wintun, "WintunSetLogger")) == NULL ||
 | 
					 | 
				
			||||||
        (WintunCreateAdapter = (WINTUN_CREATE_ADAPTER_FUNC)GetProcAddress(Wintun, "WintunCreateAdapter")) == NULL ||
 | 
					 | 
				
			||||||
        (WintunDeleteAdapter = (WINTUN_DELETE_ADAPTER_FUNC)GetProcAddress(Wintun, "WintunDeleteAdapter")) == NULL ||
 | 
					 | 
				
			||||||
        (WintunStartSession = (WINTUN_START_SESSION_FUNC)GetProcAddress(Wintun, "WintunStartSession")) == NULL ||
 | 
					 | 
				
			||||||
        (WintunEndSession = (WINTUN_END_SESSION_FUNC)GetProcAddress(Wintun, "WintunEndSession")) == NULL ||
 | 
					 | 
				
			||||||
        (WintunReceivePacket = (WINTUN_RECEIVE_PACKET_FUNC)GetProcAddress(Wintun, "WintunReceivePacket")) == NULL ||
 | 
					 | 
				
			||||||
        (WintunReceiveRelease = (WINTUN_RECEIVE_RELEASE_FUNC)GetProcAddress(Wintun, "WintunReceiveRelease")) == NULL ||
 | 
					 | 
				
			||||||
        (WintunAllocateSendPacket =
 | 
					 | 
				
			||||||
             (WINTUN_ALLOCATE_SEND_PACKET_FUNC)GetProcAddress(Wintun, "WintunAllocateSendPacket")) == NULL ||
 | 
					 | 
				
			||||||
        (WintunSendPacket = (WINTUN_SEND_PACKET_FUNC)GetProcAddress(Wintun, "WintunSendPacket")) == NULL)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Result = LogLastError(L"Failed to get wintun.dll entries");
 | 
					 | 
				
			||||||
        goto cleanupWintun;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DWORD Result;
 | 
				
			||||||
    HaveQuit = FALSE;
 | 
					    HaveQuit = FALSE;
 | 
				
			||||||
    QuitEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
 | 
					    QuitEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
 | 
				
			||||||
    if (!QuitEvent)
 | 
					    if (!QuitEvent)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Result = LogLastError(L"Failed to create event");
 | 
					        Result = LogError(L"Failed to create event", GetLastError());
 | 
				
			||||||
        goto cleanupWintun;
 | 
					        goto cleanupWintun;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    WintunSetLogger(ConsoleLogger);
 | 
					 | 
				
			||||||
    if (!SetConsoleCtrlHandler(CtrlHandler, TRUE))
 | 
					    if (!SetConsoleCtrlHandler(CtrlHandler, TRUE))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Result = LogLastError(L"Failed to set console handler");
 | 
					        Result = LogError(L"Failed to set console handler", GetLastError());
 | 
				
			||||||
        goto cleanupQuit;
 | 
					        goto cleanupQuit;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HANDLE Workers[MAXIMUM_WAIT_OBJECTS] = { 0 };
 | 
					    GUID ExampleGuid = { 0xdeadbabe, 0xcafe, 0xbeef, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef } };
 | 
				
			||||||
    for (size_t i = 0; i < _countof(Workers); ++i)
 | 
					    WINTUN_ADAPTER_HANDLE Adapter;
 | 
				
			||||||
        if (!Workers[i])
 | 
					    Result = WintunGetAdapter(L"Example", L"Demo", &Adapter);
 | 
				
			||||||
 | 
					    if (Result != ERROR_SUCCESS)
 | 
				
			||||||
 | 
					        Result = WintunCreateAdapter(L"Example", L"Demo", &ExampleGuid, &Adapter, NULL);
 | 
				
			||||||
 | 
					    if (Result != ERROR_SUCCESS)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
            Workers[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TestAdapter, (LPVOID)i, 0, NULL);
 | 
					        LogError(L"Failed to create adapter", Result);
 | 
				
			||||||
            if (!Workers[i])
 | 
					        goto cleanupQuit;
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Result = LogLastError(L"Failed to create thread");
 | 
					 | 
				
			||||||
                goto cleanupWorkers;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DWORDLONG Version = WintunGetVersion();
 | 
				
			||||||
 | 
					    Log(WINTUN_LOG_INFO,
 | 
				
			||||||
 | 
					        L"Wintun v%d.%d.%d.%d loaded",
 | 
				
			||||||
 | 
					        (Version >> 48) & 0xff,
 | 
				
			||||||
 | 
					        (Version >> 32) & 0xff,
 | 
				
			||||||
 | 
					        (Version >> 16) & 0xff,
 | 
				
			||||||
 | 
					        (Version >> 0) & 0xff,
 | 
				
			||||||
 | 
					        WINTUN_VERSION_MIN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MIB_UNICASTIPADDRESS_ROW AddressRow;
 | 
				
			||||||
 | 
					    InitializeUnicastIpAddressEntry(&AddressRow);
 | 
				
			||||||
 | 
					    WintunGetAdapterLUID(Adapter, &AddressRow.InterfaceLuid);
 | 
				
			||||||
 | 
					    AddressRow.Address.Ipv4.sin_family = AF_INET;
 | 
				
			||||||
 | 
					    AddressRow.Address.Ipv4.sin_addr.S_un.S_addr = htonl((10 << 24) | (6 << 16) | (7 << 8) | (7 << 0)); /* 10.6.7.7 */
 | 
				
			||||||
 | 
					    AddressRow.OnLinkPrefixLength = 24;                                                                 /* This is a /24 network */
 | 
				
			||||||
 | 
					    Result = CreateUnicastIpAddressEntry(&AddressRow);
 | 
				
			||||||
 | 
					    if (Result != ERROR_SUCCESS)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LogError(L"Failed to set IP address", Result);
 | 
				
			||||||
 | 
					        goto cleanupAdapter;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    WINTUN_SESSION_HANDLE Session;
 | 
				
			||||||
 | 
					    Result = WintunStartSession(Adapter, 0x40000, &Session);
 | 
				
			||||||
 | 
					    if (Result != ERROR_SUCCESS)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LogError(L"Failed to create adapter", Result);
 | 
				
			||||||
 | 
					        goto cleanupAdapter;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Log(WINTUN_LOG_INFO, L"Launching threads and mangling packets...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HANDLE Workers[] = { CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceivePackets, (LPVOID)Session, 0, NULL),
 | 
				
			||||||
 | 
					                         CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SendPackets, (LPVOID)Session, 0, NULL) };
 | 
				
			||||||
 | 
					    if (!Workers[0] || !Workers[1])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Result = LogError(L"Failed to create threads", GetLastError());
 | 
				
			||||||
 | 
					        goto cleanupWorkers;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    WaitForMultipleObjectsEx(_countof(Workers), Workers, TRUE, INFINITE, TRUE);
 | 
					    WaitForMultipleObjectsEx(_countof(Workers), Workers, TRUE, INFINITE, TRUE);
 | 
				
			||||||
    Result = ERROR_SUCCESS;
 | 
					    Result = ERROR_SUCCESS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cleanupWorkers:
 | 
					cleanupWorkers:
 | 
				
			||||||
    HaveQuit = TRUE;
 | 
					    HaveQuit = TRUE;
 | 
				
			||||||
    SetEvent(QuitEvent);
 | 
					    SetEvent(QuitEvent);
 | 
				
			||||||
    for (size_t i = 0; i < _countof(Workers); ++i)
 | 
					    for (size_t i = 0; i < _countof(Workers); ++i)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        if (Workers[i])
 | 
					        if (Workers[i])
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            WaitForSingleObject(Workers[i], INFINITE);
 | 
					            WaitForSingleObject(Workers[i], INFINITE);
 | 
				
			||||||
            CloseHandle(Workers[i]);
 | 
					            CloseHandle(Workers[i]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    SetConsoleCtrlHandler(CtrlHandler, FALSE);
 | 
					    }
 | 
				
			||||||
 | 
					    WintunEndSession(Session);
 | 
				
			||||||
 | 
					cleanupAdapter:
 | 
				
			||||||
 | 
					    WintunDeleteAdapter(Adapter, FALSE, NULL);
 | 
				
			||||||
 | 
					    WintunFreeAdapter(Adapter);
 | 
				
			||||||
cleanupQuit:
 | 
					cleanupQuit:
 | 
				
			||||||
 | 
					    SetConsoleCtrlHandler(CtrlHandler, FALSE);
 | 
				
			||||||
    CloseHandle(QuitEvent);
 | 
					    CloseHandle(QuitEvent);
 | 
				
			||||||
cleanupWintun:
 | 
					cleanupWintun:
 | 
				
			||||||
    FreeLibrary(Wintun);
 | 
					    FreeLibrary(Wintun);
 | 
				
			||||||
 | 
				
			|||||||
@ -52,17 +52,14 @@
 | 
				
			|||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
 | 
					  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
 | 
				
			||||||
  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
 | 
					  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
 | 
				
			||||||
    <ConfigurationType>Application</ConfigurationType>
 | 
					 | 
				
			||||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
					    <UseDebugLibraries>true</UseDebugLibraries>
 | 
				
			||||||
    <PlatformToolset>v142</PlatformToolset>
 | 
					 | 
				
			||||||
    <CharacterSet>Unicode</CharacterSet>
 | 
					 | 
				
			||||||
    <SpectreMitigation>false</SpectreMitigation>
 | 
					 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
 | 
					  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
 | 
				
			||||||
    <ConfigurationType>Application</ConfigurationType>
 | 
					 | 
				
			||||||
    <UseDebugLibraries>false</UseDebugLibraries>
 | 
					 | 
				
			||||||
    <PlatformToolset>v142</PlatformToolset>
 | 
					 | 
				
			||||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
					    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <PropertyGroup Label="Configuration">
 | 
				
			||||||
 | 
					    <ConfigurationType>Application</ConfigurationType>
 | 
				
			||||||
 | 
					    <PlatformToolset>v142</PlatformToolset>
 | 
				
			||||||
    <CharacterSet>Unicode</CharacterSet>
 | 
					    <CharacterSet>Unicode</CharacterSet>
 | 
				
			||||||
    <SpectreMitigation>false</SpectreMitigation>
 | 
					    <SpectreMitigation>false</SpectreMitigation>
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
@ -107,6 +104,14 @@
 | 
				
			|||||||
      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
 | 
					      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
 | 
				
			||||||
    </Link>
 | 
					    </Link>
 | 
				
			||||||
  </ItemDefinitionGroup>
 | 
					  </ItemDefinitionGroup>
 | 
				
			||||||
 | 
					  <ItemDefinitionGroup>
 | 
				
			||||||
 | 
					    <Link>
 | 
				
			||||||
 | 
					      <AdditionalDependencies>iphlpapi.lib;kernel32.lib;ntdll.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 | 
				
			||||||
 | 
					    </Link>
 | 
				
			||||||
 | 
					    <ClCompile>
 | 
				
			||||||
 | 
					      <AdditionalIncludeDirectories>..\api</AdditionalIncludeDirectories>
 | 
				
			||||||
 | 
					    </ClCompile>
 | 
				
			||||||
 | 
					  </ItemDefinitionGroup>
 | 
				
			||||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
 | 
					  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
 | 
				
			||||||
  <ImportGroup Label="ExtensionTargets">
 | 
					  <ImportGroup Label="ExtensionTargets">
 | 
				
			||||||
  </ImportGroup>
 | 
					  </ImportGroup>
 | 
				
			||||||
 | 
				
			|||||||
@ -5,14 +5,6 @@
 | 
				
			|||||||
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
 | 
					      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
 | 
				
			||||||
      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
 | 
					      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
 | 
				
			||||||
    </Filter>
 | 
					    </Filter>
 | 
				
			||||||
    <Filter Include="Header Files">
 | 
					 | 
				
			||||||
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
 | 
					 | 
				
			||||||
      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
 | 
					 | 
				
			||||||
    </Filter>
 | 
					 | 
				
			||||||
    <Filter Include="Resource Files">
 | 
					 | 
				
			||||||
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
 | 
					 | 
				
			||||||
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
 | 
					 | 
				
			||||||
    </Filter>
 | 
					 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
    <ClCompile Include="example.c">
 | 
					    <ClCompile Include="example.c">
 | 
				
			||||||
 | 
				
			|||||||
@ -64,13 +64,21 @@ Global
 | 
				
			|||||||
		{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.ActiveCfg = Release|Win32
 | 
							{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.ActiveCfg = Release|Win32
 | 
				
			||||||
		{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.Build.0 = Release|Win32
 | 
							{F7679B65-2FEC-469A-8BAC-B07BF4439422}.Release|x86.Build.0 = Release|Win32
 | 
				
			||||||
		{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|amd64.ActiveCfg = Debug|x64
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|amd64.ActiveCfg = Debug|x64
 | 
				
			||||||
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|amd64.Build.0 = Debug|x64
 | 
				
			||||||
		{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm.ActiveCfg = Debug|ARM
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm.ActiveCfg = Debug|ARM
 | 
				
			||||||
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm.Build.0 = Debug|ARM
 | 
				
			||||||
		{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm64.ActiveCfg = Debug|ARM64
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm64.ActiveCfg = Debug|ARM64
 | 
				
			||||||
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|arm64.Build.0 = Debug|ARM64
 | 
				
			||||||
		{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|x86.ActiveCfg = Debug|Win32
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|x86.ActiveCfg = Debug|Win32
 | 
				
			||||||
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Debug|x86.Build.0 = Debug|Win32
 | 
				
			||||||
		{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|amd64.ActiveCfg = Release|x64
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|amd64.ActiveCfg = Release|x64
 | 
				
			||||||
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|amd64.Build.0 = Release|x64
 | 
				
			||||||
		{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm.ActiveCfg = Release|ARM
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm.ActiveCfg = Release|ARM
 | 
				
			||||||
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm.Build.0 = Release|ARM
 | 
				
			||||||
		{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm64.ActiveCfg = Release|ARM64
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm64.ActiveCfg = Release|ARM64
 | 
				
			||||||
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|arm64.Build.0 = Release|ARM64
 | 
				
			||||||
		{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|x86.ActiveCfg = Release|Win32
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|x86.ActiveCfg = Release|Win32
 | 
				
			||||||
 | 
							{2ABAC503-245D-4F53-85C5-0F844DEF738B}.Release|x86.Build.0 = Release|Win32
 | 
				
			||||||
	EndGlobalSection
 | 
						EndGlobalSection
 | 
				
			||||||
	GlobalSection(SolutionProperties) = preSolution
 | 
						GlobalSection(SolutionProperties) = preSolution
 | 
				
			||||||
		HideSolutionNode = FALSE
 | 
							HideSolutionNode = FALSE
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user