aboutsummaryrefslogtreecommitdiffstats
path: root/api/logger.h
blob: 72853ccc67aa169ffae37931a113c5ea26356c05 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* SPDX-License-Identifier: GPL-2.0
 *
 * Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved.
 */

#pragma once

#include "wintun.h"
#include "main.h"
#include "registry.h"
#include <Windows.h>
#include <intsafe.h>
#include <stdarg.h>
#include <wchar.h>

extern WINTUN_LOGGER_CALLBACK Logger;

/**
 * @copydoc WINTUN_SET_LOGGER_FUNC
 */
WINTUN_SET_LOGGER_FUNC_IMPL WintunSetLogger;

_Post_equals_last_error_
DWORD
LoggerLog(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ LPCWSTR Function, _In_z_ LPCWSTR LogLine);

_Post_equals_last_error_
DWORD
LoggerLogV(
    _In_ WINTUN_LOGGER_LEVEL Level,
    _In_z_ LPCWSTR Function,
    _In_z_ _Printf_format_string_ LPCWSTR Format,
    _In_ va_list Args);

_Post_equals_last_error_
static inline DWORD
LoggerLogFmt(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ LPCWSTR Function, _In_z_ _Printf_format_string_ LPCWSTR Format, ...)
{
    va_list Args;
    va_start(Args, Format);
    DWORD LastError = LoggerLogV(Level, Function, Format, Args);
    va_end(Args);
    return LastError;
}

_Post_equals_last_error_
DWORD
LoggerError(_In_ DWORD Error, _In_z_ LPCWSTR Function, _In_z_ LPCWSTR Prefix);

_Post_equals_last_error_
DWORD
LoggerErrorV(
    _In_ DWORD Error,
    _In_z_ LPCWSTR Function,
    _In_z_ _Printf_format_string_ LPCWSTR Format,
    _In_ va_list Args);

_Post_equals_last_error_
static inline DWORD
LoggerErrorFmt(_In_ DWORD Error, _In_z_ LPCWSTR Function, _In_z_ _Printf_format_string_ LPCWSTR Format, ...)
{
    va_list Args;
    va_start(Args, Format);
    DWORD LastError = LoggerErrorV(Error, Function, Format, Args);
    va_end(Args);
    return LastError;
}

_Post_equals_last_error_
static inline DWORD
LoggerLastErrorV(_In_z_ LPCWSTR Function, _In_z_ _Printf_format_string_ LPCWSTR Format, _In_ va_list Args)
{
    DWORD LastError = GetLastError();
    LoggerErrorV(LastError, Function, Format, Args);
    SetLastError(LastError);
    return LastError;
}

_Post_equals_last_error_
static inline DWORD
LoggerLastErrorFmt(_In_z_ LPCWSTR Function, _In_z_ _Printf_format_string_ LPCWSTR Format, ...)
{
    va_list Args;
    va_start(Args, Format);
    DWORD LastError = LoggerLastErrorV(Function, Format, Args);
    va_end(Args);
    return LastError;
}

VOID
LoggerGetRegistryKeyPath(_In_ HKEY Key, _Out_writes_z_(MAX_REG_PATH) LPWSTR Path);

#define __L(x) L##x
#define _L(x) __L(x)
#define LOG(lvl, msg, ...) (LoggerLogFmt((lvl), _L(__FUNCTION__), msg, __VA_ARGS__))
#define LOG_ERROR(err, msg, ...) (LoggerErrorFmt((err), _L(__FUNCTION__), msg, __VA_ARGS__))
#define LOG_LAST_ERROR(msg, ...) (LoggerLastErrorFmt(_L(__FUNCTION__), msg, __VA_ARGS__))

#define RET_ERROR(Ret, Error) ((Error) == ERROR_SUCCESS ? (Ret) : (SetLastError(Error), 0))

_Must_inspect_result_
DECLSPEC_ALLOCATOR
static inline _Return_type_success_(return != NULL)
_Post_maybenull_
_Post_writable_byte_size_(Size)
VOID *
LoggerAlloc(_In_z_ LPCWSTR Function, _In_ DWORD Flags, _In_ SIZE_T Size)
{
    VOID *Data = HeapAlloc(ModuleHeap, Flags, Size);
    if (!Data)
    {
        LoggerLogFmt(WINTUN_LOG_ERR, Function, L"Out of memory (flags: 0x%x, requested size: 0x%zx)", Flags, Size);
        SetLastError(ERROR_OUTOFMEMORY);
    }
    return Data;
}
_Must_inspect_result_
DECLSPEC_ALLOCATOR
static inline _Return_type_success_(return != NULL)
_Post_maybenull_
_Post_writable_byte_size_(Size)
VOID *
LoggerReAlloc(_In_z_ LPCWSTR Function, _In_ DWORD Flags, _Frees_ptr_opt_ LPVOID Mem, _In_ SIZE_T Size)
{
    VOID *Data = Mem ? HeapReAlloc(ModuleHeap, Flags, Mem, Size) : HeapAlloc(ModuleHeap, Flags, Size);
    if (!Data)
    {
        LoggerLogFmt(WINTUN_LOG_ERR, Function, L"Out of memory (flags: 0x%x, requested size: 0x%zx)", Flags, Size);
        SetLastError(ERROR_OUTOFMEMORY);
    }
    return Data;
}
#define Alloc(Size) LoggerAlloc(_L(__FUNCTION__), 0, Size)
#define ReAlloc(Mem, Size) LoggerReAlloc(_L(__FUNCTION__), 0, Mem, Size)
#define Zalloc(Size) LoggerAlloc(_L(__FUNCTION__), HEAP_ZERO_MEMORY, Size)
#define ReZalloc(Mem, Size) LoggerReAlloc(_L(__FUNCTION__), HEAP_ZERO_MEMORY, Mem, Size)

_Must_inspect_result_
DECLSPEC_ALLOCATOR
static inline _Return_type_success_(return != NULL)
_Post_maybenull_
_Post_writable_byte_size_((NumberOfElements) * (SizeOfOneElement))
VOID *
LoggerAllocArray(_In_z_ LPCWSTR Function, _In_ DWORD Flags, _In_ SIZE_T NumberOfElements, _In_ SIZE_T SizeOfOneElement)
{
    SIZE_T Size;
    if (FAILED(SIZETMult(NumberOfElements, SizeOfOneElement, &Size)))
        return NULL;
    return LoggerAlloc(Function, Flags, Size);
}
_Must_inspect_result_
DECLSPEC_ALLOCATOR
static inline _Return_type_success_(return != NULL)
_Post_maybenull_
_Post_writable_byte_size_((NumberOfElements) * (SizeOfOneElement))
VOID *
LoggerReAllocArray(
    _In_z_ LPCWSTR Function,
    _In_ DWORD Flags,
    _Frees_ptr_opt_ LPVOID Mem,
    _In_ SIZE_T NumberOfElements,
    _In_ SIZE_T SizeOfOneElement)
{
    SIZE_T Size;
    if (FAILED(SIZETMult(NumberOfElements, SizeOfOneElement, &Size)))
        return NULL;
    return LoggerReAlloc(Function, Flags, Mem, Size);
}
#define AllocArray(Count, Size) LoggerAllocArray(_L(__FUNCTION__), 0, Count, Size)
#define ReAllocArray(Mem, Count, Size) LoggerReAllocArray(_L(__FUNCTION__), 0, Mem, Count, Size)
#define ZallocArray(Count, Size) LoggerAllocArray(_L(__FUNCTION__), HEAP_ZERO_MEMORY, Count, Size)
#define ReZallocArray(Mem, Count, Size) LoggerReAllocArray(_L(__FUNCTION__), HEAP_ZERO_MEMORY, Mem, Count, Size)

static inline VOID
Free(_Frees_ptr_opt_ VOID *Ptr)
{
    if (!Ptr)
        return;
    DWORD LastError = GetLastError();
    HeapFree(ModuleHeap, 0, Ptr);
    SetLastError(LastError);
}