diff --git a/dll/windivert.c b/dll/windivert.c
index af220e5..323c27c 100644
--- a/dll/windivert.c
+++ b/dll/windivert.c
@@ -56,6 +56,7 @@
#define ERROR_DRIVER_FAILED_PRIOR_UNLOAD ((DWORD)654)
#endif
+static BOOLEAN WinDivertIsDigit(char c);
static BOOLEAN WinDivertIsXDigit(char c);
static BOOLEAN WinDivertIsSpace(char c);
static BOOLEAN WinDivertIsAlNum(char c);
@@ -69,6 +70,7 @@ static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr,
UINT size);
static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr,
UINT size, BOOL prefix);
+static UINT32 WinDivertDivTen128(UINT32 *a);
/*
* Misc.
@@ -76,10 +78,37 @@ static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr,
#ifndef UINT8_MAX
#define UINT8_MAX 0xFF
#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX 0xFFFF
+#endif
#ifndef UINT32_MAX
#define UINT32_MAX 0xFFFFFFFF
#endif
+#ifdef _MSC_VER
+
+#pragma intrinsic(memcpy)
+#pragma function(memcpy)
+void *memcpy(void *dst, const void *src, size_t n)
+{
+ size_t i;
+ for (i = 0; i < n; i++)
+ ((UINT8 *)dst)[i] = ((const UINT8 *)src)[i];
+ return dst;
+}
+
+#pragma intrinsic(memset)
+#pragma function(memset)
+void *memset(void *dst, int c, size_t n)
+{
+ size_t i;
+ for (i = 0; i < n; i++)
+ ((UINT8 *)dst)[i] = (UINT8)c;
+ return dst;
+}
+
+#endif
+
/*
* Prototypes.
*/
@@ -377,11 +406,11 @@ static BOOL WinDivertIoControl(HANDLE handle, DWORD code,
extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
INT16 priority, UINT64 flags)
{
- WINDIVERT_FILTER object[WINDIVERT_FILTER_MAXLEN];
+ WINDIVERT_FILTER *object;
UINT obj_len;
ERROR comp_err;
DWORD err;
- HANDLE handle;
+ HANDLE handle, pool;
UINT64 filter_flags;
WINDIVERT_IOCTL ioctl;
WINDIVERT_VERSION version;
@@ -393,7 +422,7 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
offsetof(WINDIVERT_DATA_SOCKET, Protocol) != 56 ||
offsetof(WINDIVERT_DATA_REFLECT, Priority) != 24 ||
sizeof(WINDIVERT_FILTER) != 24 ||
- offsetof(WINDIVERT_ADDRESS, Reserved2) != 16)
+ offsetof(WINDIVERT_ADDRESS, Reserved3) != 16)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
@@ -426,9 +455,25 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
}
// Compile & analyze the filter:
- comp_err = WinDivertCompileFilter(filter, layer, object, &obj_len);
+ pool = HeapCreate(HEAP_NO_SERIALIZE, WINDIVERT_MIN_POOL_SIZE,
+ WINDIVERT_MAX_POOL_SIZE);
+ if (pool == NULL)
+ {
+ return FALSE;
+ }
+ object = HeapAlloc(pool, 0,
+ WINDIVERT_FILTER_MAXLEN * sizeof(WINDIVERT_FILTER));
+ if (object == NULL)
+ {
+ err = GetLastError();
+ HeapDestroy(pool);
+ SetLastError(err);
+ return FALSE;
+ }
+ comp_err = WinDivertCompileFilter(filter, pool, layer, object, &obj_len);
if (IS_ERROR(comp_err))
{
+ HeapDestroy(pool);
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
@@ -443,31 +488,36 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
err = GetLastError();
if (err != ERROR_FILE_NOT_FOUND && err != ERROR_PATH_NOT_FOUND)
{
+ HeapDestroy(pool);
+ SetLastError(err);
return INVALID_HANDLE_VALUE;
}
// Open failed because the device isn't installed; install it now.
if ((flags & WINDIVERT_FLAG_NO_INSTALL) != 0)
{
+ HeapDestroy(pool);
SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
return INVALID_HANDLE_VALUE;
}
SetLastError(0);
if (!WinDivertDriverInstall())
{
- if (GetLastError() == 0)
- {
- SetLastError(ERROR_OPEN_FAILED);
- }
+ err = GetLastError();
+ err = (err == 0? ERROR_OPEN_FAILED: err);
+ HeapDestroy(pool);
+ SetLastError(err);
return INVALID_HANDLE_VALUE;
}
handle = CreateFile(L"\\\\.\\" WINDIVERT_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
INVALID_HANDLE_VALUE);
-
if (handle == INVALID_HANDLE_VALUE)
{
+ err = GetLastError();
+ HeapDestroy(pool);
+ SetLastError(err);
return INVALID_HANDLE_VALUE;
}
}
@@ -485,13 +535,17 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_INITIALIZE, &ioctl,
&version, sizeof(version), NULL))
{
+ err = GetLastError();
CloseHandle(handle);
+ HeapDestroy(pool);
+ SetLastError(err);
return INVALID_HANDLE_VALUE;
}
if (version.magic != WINDIVERT_MAGIC_SYS ||
version.major < WINDIVERT_VERSION_MAJOR_MIN)
{
CloseHandle(handle);
+ HeapDestroy(pool);
SetLastError(ERROR_DRIVER_FAILED_PRIOR_UNLOAD);
return INVALID_HANDLE_VALUE;
}
@@ -502,9 +556,13 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_STARTUP, &ioctl,
object, obj_len * sizeof(WINDIVERT_FILTER), NULL))
{
+ err = GetLastError();
CloseHandle(handle);
+ HeapDestroy(pool);
+ SetLastError(err);
return INVALID_HANDLE_VALUE;
}
+ HeapDestroy(pool);
// Success!
return handle;
@@ -645,6 +703,11 @@ extern BOOL WinDivertGetParam(HANDLE handle, WINDIVERT_PARAM param,
/* REPLACEMENTS */
/*****************************************************************************/
+static BOOLEAN WinDivertIsDigit(char c)
+{
+ return (c >= '0' && c <= '9');
+}
+
static BOOLEAN WinDivertIsXDigit(char c)
{
return (c >= '0' && c <= '9') ||
@@ -756,7 +819,7 @@ static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr,
size_t i = 0;
UINT32 n[4] = {0};
BOOLEAN result = TRUE;
- for (; str[i] && isdigit(str[i]); i++)
+ for (; str[i] && WinDivertIsDigit(str[i]); i++)
{
if (!WinDivertMul128(n, 10) || !WinDivertAdd128(n, str[i] - '0'))
{
@@ -801,7 +864,7 @@ static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr,
}
for (; str[i] && WinDivertIsXDigit(str[i]); i++)
{
- if (isdigit(str[i]))
+ if (WinDivertIsDigit(str[i]))
{
dig = (UINT32)(str[i] - '0');
}
@@ -833,3 +896,47 @@ static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr,
return result;
}
+/*
+ * Divide by 10 and return the remainder.
+ */
+#define WINDIVERT_BIG_MUL_ROUND(a, c, r, i) \
+ do { \
+ UINT64 t = WINDIVERT_MUL64((UINT64)(a), (UINT64)(c)); \
+ UINT k; \
+ for (k = (i); k < 9 && t != 0; k++) \
+ { \
+ UINT64 s = (UINT64)(r)[k] + (t & 0xFFFFFFFF); \
+ (r)[k] = (UINT32)s; \
+ t = (t >> 32) + (s >> 32); \
+ } \
+ } while (FALSE)
+static UINT32 WinDivertDivTen128(UINT32 *a)
+{
+ const UINT32 c[5] =
+ {
+ 0x9999999A, 0x99999999, 0x99999999, 0x99999999, 0x19999999
+ };
+ UINT32 r[9] = {0}, m[6] = {0};
+ UINT i, j;
+
+ for (i = 0; i < 4; i++)
+ {
+ for (j = 0; j < 5; j++)
+ {
+ WINDIVERT_BIG_MUL_ROUND(a[i], c[j], r, i+j);
+ }
+ }
+
+ a[0] = r[5];
+ a[1] = r[6];
+ a[2] = r[7];
+ a[3] = r[8];
+
+ for (i = 0; i < 5; i++)
+ {
+ WINDIVERT_BIG_MUL_ROUND(r[i], 10, m, i);
+ }
+
+ return m[5];
+}
+
diff --git a/dll/windivert.def b/dll/windivert.def
index 8d28d44..523bfda 100644
--- a/dll/windivert.def
+++ b/dll/windivert.def
@@ -1,6 +1,5 @@
LIBRARY WinDivert
EXPORTS
- WinDivertDllEntry
WinDivertOpen
WinDivertRecv
WinDivertRecvEx
diff --git a/dll/windivert.vcxproj b/dll/windivert.vcxproj
new file mode 100644
index 0000000..caab874
--- /dev/null
+++ b/dll/windivert.vcxproj
@@ -0,0 +1,84 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MinSpace
+ true
+ Default
+ false
+ ..\include
+
+
+
+ WinDivert
+ WinDivert
+
+
+
+ v140
+ true
+ DynamicLibrary
+
+
+
+
+ false
+ WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions)
+ WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions)
+
+
+ WinDivertDllEntry
+ %(AdditionalDependencies)
+ true
+ windivert.def
+ WinDivert.lib
+
+
+
+
diff --git a/dll/windivert_hash.c b/dll/windivert_hash.c
index 2d7caa9..3efba83 100644
--- a/dll/windivert_hash.c
+++ b/dll/windivert_hash.c
@@ -68,7 +68,7 @@
* only ever a single round. As such, the algorithm has been specialized.
*/
-#define WINDIVERT_ROTL(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
+#define WINDIVERT_ROTL64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
static const UINT64 WINDIVERT_PRIME64_1 = 11400714785074694791ull;
static const UINT64 WINDIVERT_PRIME64_2 = 14029467366897019727ull;
@@ -77,9 +77,9 @@ static const UINT64 WINDIVERT_PRIME64_4 = 9650029242287828579ull;
static UINT64 WinDivertXXH64Round(UINT64 acc, UINT64 input)
{
- acc += input * WINDIVERT_PRIME64_2;
- acc = WINDIVERT_ROTL(acc, 31);
- acc *= WINDIVERT_PRIME64_1;
+ acc += WINDIVERT_MUL64(input, WINDIVERT_PRIME64_2);
+ acc = WINDIVERT_ROTL64(acc, 31);
+ acc = WINDIVERT_MUL64(acc, WINDIVERT_PRIME64_1);
return acc;
}
@@ -87,16 +87,16 @@ static UINT64 WinDivertXXH64MergeRound(UINT64 acc, UINT64 val)
{
val = WinDivertXXH64Round(0, val);
acc ^= val;
- acc = acc * WINDIVERT_PRIME64_1 + WINDIVERT_PRIME64_4;
+ acc = WINDIVERT_MUL64(acc, WINDIVERT_PRIME64_1) + WINDIVERT_PRIME64_4;
return acc;
}
static UINT64 WinDivertXXH64Avalanche(UINT64 h64)
{
h64 ^= h64 >> 33;
- h64 *= WINDIVERT_PRIME64_2;
+ h64 = WINDIVERT_MUL64(h64, WINDIVERT_PRIME64_2);
h64 ^= h64 >> 29;
- h64 *= WINDIVERT_PRIME64_3;
+ h64 = WINDIVERT_MUL64(h64, WINDIVERT_PRIME64_3);
h64 ^= h64 >> 32;
return h64;
}
@@ -187,8 +187,8 @@ static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
v2 = WinDivertXXH64Round(v[1], v2);
v3 = WinDivertXXH64Round(v[2], v3);
v4 = WinDivertXXH64Round(v[3], v4);
- h64 = WINDIVERT_ROTL(v1, 1) + WINDIVERT_ROTL(v2, 7) +
- WINDIVERT_ROTL(v3, 12) + WINDIVERT_ROTL(v4, 18);
+ h64 = WINDIVERT_ROTL64(v1, 1) + WINDIVERT_ROTL64(v2, 7) +
+ WINDIVERT_ROTL64(v3, 12) + WINDIVERT_ROTL64(v4, 18);
h64 = WinDivertXXH64MergeRound(h64, v1);
h64 = WinDivertXXH64MergeRound(h64, v2);
h64 = WinDivertXXH64MergeRound(h64, v3);
diff --git a/dll/windivert_helper.c b/dll/windivert_helper.c
index 61b41a3..3e1429f 100644
--- a/dll/windivert_helper.c
+++ b/dll/windivert_helper.c
@@ -276,6 +276,9 @@ typedef UINT64 ERROR, *PERROR;
#define WINDIVERT_ERROR_BAD_OBJECT 9
#define WINDIVERT_ERROR_ASSERTION_FAILED 10
+#define WINDIVERT_MIN_POOL_SIZE 12288
+#define WINDIVERT_MAX_POOL_SIZE 131072
+
#define MAKE_ERROR(code, pos) \
(((ERROR)(code) << 32) | (ERROR)(pos));
#define GET_CODE(err) \
@@ -2282,16 +2285,14 @@ static BOOL WinDivertCondExecFilter(PWINDIVERT_FILTER filter, UINT length,
/*
* Compile a filter string into an executable filter object.
*/
-static ERROR WinDivertCompileFilter(const char *filter,
+static ERROR WinDivertCompileFilter(const char *filter, HANDLE pool,
WINDIVERT_LAYER layer, PWINDIVERT_FILTER object, UINT *obj_len)
{
TOKEN *tokens;
PEXPR *stack;
- HANDLE pool;
PEXPR expr;
UINT i, max_depth, pos;
INT16 label;
- const SIZE_T min_pool_size = 8192;
const SIZE_T tokens_size = 5 * WINDIVERT_FILTER_MAXLEN;
ERROR error;
@@ -2312,18 +2313,11 @@ static ERROR WinDivertCompileFilter(const char *filter,
return MAKE_ERROR(WINDIVERT_ERROR_NONE, 0);
}
- // Allocate memory for the compiler:
- pool = HeapCreate(HEAP_NO_SERIALIZE, min_pool_size, 16 * min_pool_size);
- if (pool == NULL)
- {
- return MAKE_ERROR(WINDIVERT_ERROR_NO_MEMORY, 0);
- }
tokens = (TOKEN *)HeapAlloc(pool, 0, tokens_size * sizeof(TOKEN));
stack = (PEXPR *)HeapAlloc(pool, 0,
WINDIVERT_FILTER_MAXLEN * sizeof(PEXPR));
if (tokens == NULL || stack == NULL)
{
- HeapDestroy(pool);
return MAKE_ERROR(WINDIVERT_ERROR_NO_MEMORY, 0);
}
@@ -2331,7 +2325,6 @@ static ERROR WinDivertCompileFilter(const char *filter,
error = WinDivertTokenizeFilter(filter, layer, tokens, tokens_size-1);
if (IS_ERROR(error))
{
- HeapDestroy(pool);
return error;
}
@@ -2341,13 +2334,11 @@ static ERROR WinDivertCompileFilter(const char *filter,
expr = WinDivertParseFilter(pool, tokens, &i, max_depth, FALSE, &error);
if (expr == NULL)
{
- HeapDestroy(pool);
return error;
}
if (tokens[i].kind != TOKEN_END)
{
pos = tokens[i].pos;
- HeapDestroy(pool);
return MAKE_ERROR(WINDIVERT_ERROR_UNEXPECTED_TOKEN, pos);
}
@@ -2357,7 +2348,6 @@ static ERROR WinDivertCompileFilter(const char *filter,
WINDIVERT_FILTER_RESULT_REJECT, stack);
if (label < 0)
{
- HeapDestroy(pool);
return MAKE_ERROR(WINDIVERT_ERROR_TOO_LONG, 0);
}
@@ -2366,7 +2356,6 @@ static ERROR WinDivertCompileFilter(const char *filter,
{
WinDivertEmitFilter(stack, label, label, object, obj_len);
}
- HeapDestroy(pool);
return MAKE_ERROR(WINDIVERT_ERROR_NONE, 0);
}
@@ -2412,39 +2401,56 @@ extern BOOL WinDivertHelperCompileFilter(const char *filter_str,
WINDIVERT_LAYER layer, char *object, UINT obj_len, const char **error,
UINT *error_pos)
{
+ HANDLE pool;
ERROR err;
+
if (filter_str == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
+ pool = HeapCreate(HEAP_NO_SERIALIZE, WINDIVERT_MIN_POOL_SIZE,
+ WINDIVERT_MAX_POOL_SIZE);
+ if (pool == NULL)
+ {
+ return FALSE;
+ }
+
SetLastError(ERROR_SUCCESS);
if (object == NULL)
{
- err = WinDivertCompileFilter(filter_str, layer, NULL, NULL);
+ err = WinDivertCompileFilter(filter_str, pool, layer, NULL, NULL);
}
else
{
- WINDIVERT_FILTER object0[WINDIVERT_FILTER_MAXLEN];
- UINT obj0_len;
- err = WinDivertCompileFilter(filter_str, layer, object0, &obj0_len);
- if (!IS_ERROR(err))
+ WINDIVERT_FILTER *filter_obj = HeapAlloc(pool, 0,
+ WINDIVERT_FILTER_MAXLEN * sizeof(WINDIVERT_FILTER));
+ UINT filter_obj_len;
+ err = WINDIVERT_ERROR_NO_MEMORY;
+ if (filter_obj != NULL)
{
- WINDIVERT_STREAM stream;
- stream.data = object;
- stream.pos = 0;
- stream.max = obj_len;
- stream.overflow = FALSE;
-
- WinDivertSerializeFilter(&stream, object0, obj0_len);
- if (stream.overflow)
+ err = WinDivertCompileFilter(filter_str, pool, layer, filter_obj,
+ &filter_obj_len);
+ if (!IS_ERROR(err))
{
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- err = MAKE_ERROR(WINDIVERT_ERROR_OUTPUT_TOO_SHORT, 0);
+ WINDIVERT_STREAM stream;
+ stream.data = object;
+ stream.pos = 0;
+ stream.max = obj_len;
+ stream.overflow = FALSE;
+
+ WinDivertSerializeFilter(&stream, filter_obj, filter_obj_len);
+ if (stream.overflow)
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ err = MAKE_ERROR(WINDIVERT_ERROR_OUTPUT_TOO_SHORT, 0);
+ }
}
}
}
+ HeapDestroy(pool);
+
if (error != NULL)
{
*error = WinDivertErrorString(GET_CODE(err));
@@ -2540,6 +2546,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
{
UINT16 pc;
ERROR err;
+ DWORD error;
PWINDIVERT_IPHDR iphdr = NULL;
PWINDIVERT_IPV6HDR ipv6hdr = NULL;
PWINDIVERT_ICMPHDR icmphdr = NULL;
@@ -2551,12 +2558,14 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
UINT64 random64 = 0;
BOOL neg;
UINT32 val[4];
+ ULARGE_INTEGER val64;
UINT8 data8;
UINT16 data16;
UINT32 data32;
BOOL pass, big;
int cmp;
- WINDIVERT_FILTER object[WINDIVERT_FILTER_MAXLEN];
+ HANDLE pool;
+ WINDIVERT_FILTER *object;
UINT obj_len;
if (filter == NULL || addr == NULL)
@@ -2603,11 +2612,23 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
return FALSE;
}
- err = WinDivertCompileFilter(filter, addr->Layer, object, &obj_len);
+ pool = HeapCreate(HEAP_NO_SERIALIZE, WINDIVERT_MIN_POOL_SIZE,
+ WINDIVERT_MAX_POOL_SIZE);
+ if (pool == NULL)
+ {
+ return FALSE;
+ }
+ object = HeapAlloc(pool, 0,
+ WINDIVERT_FILTER_MAXLEN * sizeof(WINDIVERT_FILTER));
+ if (object == NULL)
+ {
+ goto WinDivertHelperEvalFilterError;
+ }
+ err = WinDivertCompileFilter(filter, pool, addr->Layer, object, &obj_len);
if (IS_ERROR(err))
{
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
pc = 0;
@@ -2616,14 +2637,17 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
switch (pc)
{
case WINDIVERT_FILTER_RESULT_ACCEPT:
+ HeapDestroy(pool);
return TRUE;
case WINDIVERT_FILTER_RESULT_REJECT:
+ HeapDestroy(pool);
+ SetLastError(0);
return FALSE;
default:
if (pc >= obj_len)
{
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
}
@@ -2774,7 +2798,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
if (!pass)
{
@@ -2801,10 +2825,12 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
}
case WINDIVERT_FILTER_FIELD_RANDOM8:
- val[0] = (UINT32)((random64 >> 48) & 0xFF);
+ val64.QuadPart = random64;
+ val[0] = ((UINT32)val64.HighPart >> 16) & 0xFF;
break;
case WINDIVERT_FILTER_FIELD_RANDOM16:
- val[0] = (UINT32)((random64 >> 32) & 0xFFFF);
+ val64.QuadPart = random64;
+ val[0] = (UINT32)val64.HighPart & 0xFFFF;
break;
case WINDIVERT_FILTER_FIELD_RANDOM32:
val[0] = (UINT32)random64;
@@ -2829,12 +2855,12 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
case WINDIVERT_FILTER_FIELD_TIMESTAMP:
{
- UINT64 val64;
neg = (addr->Timestamp < 0);
- val64 = (UINT64)(neg? -addr->Timestamp: addr->Timestamp);
+ val64.QuadPart =
+ (UINT64)(neg? -addr->Timestamp: addr->Timestamp);
big = TRUE;
- val[0] = (UINT32)val64;
- val[1] = (UINT32)(val64 >> 32);
+ val[0] = (UINT32)val64.LowPart;
+ val[1] = (UINT32)val64.HighPart;
val[2] = val[3] = 0;
break;
}
@@ -2897,7 +2923,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_ICMPV6:
@@ -2917,7 +2943,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_TCP:
@@ -2935,7 +2961,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_UDP:
@@ -2953,7 +2979,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
@@ -3148,7 +3174,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_REMOTEADDR:
@@ -3192,7 +3218,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_LOCALPORT:
@@ -3230,7 +3256,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_REMOTEPORT:
@@ -3268,7 +3294,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_PROTOCOL:
@@ -3285,7 +3311,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
@@ -3294,16 +3320,18 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
switch (addr->Layer)
{
case WINDIVERT_LAYER_FLOW:
- val[0] = (UINT32)addr->Flow.EndpointId;
- val[1] = (UINT32)(addr->Flow.EndpointId >> 32);
+ val64.QuadPart = addr->Flow.EndpointId;
+ val[0] = (UINT32)val64.LowPart;
+ val[1] = (UINT32)val64.HighPart;
break;
case WINDIVERT_LAYER_SOCKET:
- val[0] = (UINT32)addr->Socket.EndpointId;
- val[1] = (UINT32)(addr->Socket.EndpointId >> 32);
+ val64.QuadPart = addr->Socket.EndpointId;
+ val[0] = (UINT32)val64.LowPart;
+ val[1] = (UINT32)val64.HighPart;
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
@@ -3312,16 +3340,18 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
switch (addr->Layer)
{
case WINDIVERT_LAYER_FLOW:
- val[0] = (UINT32)addr->Flow.ParentEndpointId;
- val[1] = (UINT32)(addr->Flow.ParentEndpointId >> 32);
+ val64.QuadPart = addr->Flow.ParentEndpointId;
+ val[0] = (UINT32)val64.LowPart;
+ val[1] = (UINT32)val64.HighPart;
break;
case WINDIVERT_LAYER_SOCKET:
- val[0] = (UINT32)addr->Socket.ParentEndpointId;
- val[1] = (UINT32)(addr->Socket.ParentEndpointId >> 32);
+ val64.QuadPart = addr->Socket.ParentEndpointId;
+ val[0] = (UINT32)val64.LowPart;
+ val[1] = (UINT32)val64.HighPart;
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
case WINDIVERT_FILTER_FIELD_PROCESSID:
@@ -3338,12 +3368,12 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
if (!pass)
{
@@ -3374,10 +3404,16 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperEvalFilterError;
}
pc = (pass? object[pc].success: object[pc].failure);
}
+
+WinDivertHelperEvalFilterError:
+ error = GetLastError();
+ HeapDestroy(pool);
+ SetLastError(error);
+ return FALSE;
}
/*
@@ -3508,6 +3544,7 @@ static BOOL WinDivertDeserializeTest(PWINDIVERT_STREAM stream,
PWINDIVERT_FILTER filter)
{
UINT32 val;
+ UINT16 success, failure;
UINT i;
if (WinDivertGetChar(stream) != '_')
@@ -3589,11 +3626,13 @@ static BOOL WinDivertDeserializeTest(PWINDIVERT_STREAM stream,
break;
}
- if (!WinDivertDeserializeLabel(stream, &filter->success) ||
- !WinDivertDeserializeLabel(stream, &filter->failure))
+ if (!WinDivertDeserializeLabel(stream, &success) ||
+ !WinDivertDeserializeLabel(stream, &failure))
{
return FALSE;
}
+ filter->success = success;
+ filter->failure = failure;
return TRUE;
}
@@ -4178,11 +4217,11 @@ static PEXPR WinDivertCoalesceExpr(HANDLE pool, PEXPR *exprs, UINT16 i)
}
/*
- * Format a decimal number.
+ * Format a 32bit decimal number.
*/
-static void WinDivertFormatDecNumber(PWINDIVERT_STREAM stream, UINT64 val)
+static void WinDivertFormatDecNumber32(PWINDIVERT_STREAM stream, UINT32 val)
{
- UINT64 r = 10000000000000000000ull, dig;
+ UINT32 r = 1000000000ul, dig;
BOOL zeroes = FALSE;
while (r != 0)
@@ -4200,9 +4239,40 @@ static void WinDivertFormatDecNumber(PWINDIVERT_STREAM stream, UINT64 val)
}
/*
- * Format a hexidecimal number.
+ * Format a 128bit decimal number.
*/
-static void WinDivertFormatHexNumber(PWINDIVERT_STREAM stream, UINT32 *val)
+static void WinDivertFormatDecNumber(PWINDIVERT_STREAM stream,
+ const UINT32 *val0)
+{
+ UINT32 val[4];
+ char buf[40];
+ UINT i, j;
+
+ if (val0[0] == 0 && val0[1] == 0 && val0[2] == 0 && val0[3] == 0)
+ {
+ WinDivertPutChar(stream, '0');
+ return;
+ }
+ val[0] = val0[0];
+ val[1] = val0[1];
+ val[2] = val0[2];
+ val[3] = val0[3];
+ for (i = 0; i < sizeof(buf) &&
+ (val[0] != 0 || val[1] != 0 || val[2] != 0 || val[3] != 0); i++)
+ {
+ buf[i] = '0' + WinDivertDivTen128(val);
+ }
+ for (j = 0; j < i; j++)
+ {
+ WinDivertPutChar(stream, buf[i - j - 1]);
+ }
+}
+
+/*
+ * Format a 128bit hexidecimal number.
+ */
+static void WinDivertFormatHexNumber(PWINDIVERT_STREAM stream,
+ const UINT32 *val)
{
INT i, s;
UINT32 dig;
@@ -4231,34 +4301,18 @@ static void WinDivertFormatHexNumber(PWINDIVERT_STREAM stream, UINT32 *val)
}
}
-/*
- * Format a big number.
- */
-static void WinDivertFormatNumber(PWINDIVERT_STREAM stream, UINT32 *val)
-{
- if (val[2] == 0 && val[3] == 0)
- {
- UINT64 val64 = ((UINT64)val[1] << 32) | (UINT64)val[0];
- WinDivertFormatDecNumber(stream, val64);
- }
- else
- {
- WinDivertFormatHexNumber(stream, val);
- }
-}
-
/*
* Format an IPv4 address.
*/
static void WinDivertFormatIPv4Addr(PWINDIVERT_STREAM stream, UINT32 addr)
{
- WinDivertFormatDecNumber(stream, (addr & 0xFF000000) >> 24);
+ WinDivertFormatDecNumber32(stream, (addr & 0xFF000000) >> 24);
WinDivertPutChar(stream, '.');
- WinDivertFormatDecNumber(stream, (addr & 0x00FF0000) >> 16);
+ WinDivertFormatDecNumber32(stream, (addr & 0x00FF0000) >> 16);
WinDivertPutChar(stream, '.');
- WinDivertFormatDecNumber(stream, (addr & 0x0000FF00) >> 8);
+ WinDivertFormatDecNumber32(stream, (addr & 0x0000FF00) >> 8);
WinDivertPutChar(stream, '.');
- WinDivertFormatDecNumber(stream, (addr & 0x000000FF) >> 0);
+ WinDivertFormatDecNumber32(stream, (addr & 0x000000FF) >> 0);
}
/*
@@ -4488,7 +4542,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
case WINDIVERT_LAYER_REFLECT:
WinDivertPutString(stream, "REFLECT"); break;
default:
- WinDivertFormatDecNumber(stream, val->val[0]); break;
+ WinDivertFormatDecNumber32(stream, val->val[0]); break;
}
}
else if (is_event)
@@ -4503,7 +4557,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
}
else
{
- WinDivertFormatDecNumber(stream, val->val[0]);
+ WinDivertFormatDecNumber32(stream, val->val[0]);
}
break;
case WINDIVERT_LAYER_FLOW:
@@ -4514,7 +4568,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
case WINDIVERT_EVENT_FLOW_DELETED:
WinDivertPutString(stream, "DELETED"); break;
default:
- WinDivertFormatDecNumber(stream, val->val[0]); break;
+ WinDivertFormatDecNumber32(stream, val->val[0]); break;
}
break;
case WINDIVERT_LAYER_SOCKET:
@@ -4531,7 +4585,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
case WINDIVERT_EVENT_SOCKET_CLOSE:
WinDivertPutString(stream, "CLOSE"); break;
default:
- WinDivertFormatDecNumber(stream, val->val[0]); break;
+ WinDivertFormatDecNumber32(stream, val->val[0]); break;
}
break;
case WINDIVERT_LAYER_REFLECT:
@@ -4542,11 +4596,11 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
case WINDIVERT_EVENT_REFLECT_CLOSE:
WinDivertPutString(stream, "CLOSE"); break;
default:
- WinDivertFormatDecNumber(stream, val->val[0]); break;
+ WinDivertFormatDecNumber32(stream, val->val[0]); break;
}
break;
default:
- WinDivertFormatDecNumber(stream, val->val[0]); break;
+ WinDivertFormatDecNumber32(stream, val->val[0]); break;
}
}
else if (is_hex)
@@ -4556,7 +4610,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
}
else
{
- WinDivertFormatNumber(stream, val->val);
+ WinDivertFormatDecNumber(stream, val->val);
}
}
@@ -4802,7 +4856,7 @@ static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
case TOKEN_PRIORITY:
WinDivertPutString(stream, "priority"); return;
case TOKEN_NUMBER:
- WinDivertFormatNumber(stream, expr->val); return;
+ WinDivertFormatDecNumber(stream, expr->val); return;
}
WinDivertPutChar(stream, '[');
@@ -4812,7 +4866,7 @@ static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
WinDivertPutChar(stream, '-');
idx = -idx;
}
- WinDivertFormatDecNumber(stream, (UINT64)idx);
+ WinDivertFormatDecNumber32(stream, (UINT32)idx);
WinDivertPutString(stream, "b]");
}
@@ -4824,13 +4878,12 @@ BOOL WinDivertHelperFormatFilter(const char *filter, WINDIVERT_LAYER layer,
{
PEXPR exprs[WINDIVERT_FILTER_MAXLEN], expr;
ERROR err;
- WINDIVERT_FILTER object[WINDIVERT_FILTER_MAXLEN];
+ DWORD error;
+ WINDIVERT_FILTER *object;
UINT obj_len;
INT i;
HANDLE pool;
WINDIVERT_STREAM stream;
- ERROR error;
- const SIZE_T min_pool_size = 8192;
if (filter == NULL || buffer == NULL)
{
@@ -4838,18 +4891,24 @@ BOOL WinDivertHelperFormatFilter(const char *filter, WINDIVERT_LAYER layer,
return FALSE;
}
- err = WinDivertCompileFilter(filter, layer, object, &obj_len);
- if (IS_ERROR(err))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- pool = HeapCreate(HEAP_NO_SERIALIZE, min_pool_size, 16 * min_pool_size);
+ pool = HeapCreate(HEAP_NO_SERIALIZE, WINDIVERT_MIN_POOL_SIZE,
+ WINDIVERT_MAX_POOL_SIZE);
if (pool == NULL)
{
return FALSE;
}
+ object = HeapAlloc(pool, 0,
+ WINDIVERT_FILTER_MAXLEN * sizeof(WINDIVERT_FILTER));
+ if (object == NULL)
+ {
+ goto WinDivertHelperFormatFilterError;
+ }
+ err = WinDivertCompileFilter(filter, pool, layer, object, &obj_len);
+ if (IS_ERROR(err))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ goto WinDivertHelperFormatFilterError;
+ }
// Decompile all tests:
for (i = (INT)obj_len-1; i >= 0; i--)
@@ -4858,7 +4917,7 @@ BOOL WinDivertHelperFormatFilter(const char *filter, WINDIVERT_LAYER layer,
if (expr == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto WinDivertHelperFormatFilterError;
}
exprs[i] = expr;
switch (expr->succ)
@@ -4885,12 +4944,11 @@ BOOL WinDivertHelperFormatFilter(const char *filter, WINDIVERT_LAYER layer,
// Coalesce (unflatten) tests into and/or expressions:
for (i = (INT)obj_len-1; i >= 0; i--)
{
- error = MAKE_ERROR(WINDIVERT_ERROR_NONE, 0);
- (PVOID)WinDivertCoalesceAndOr(pool, exprs, i, &error);
- if (IS_ERROR(error))
+ err = MAKE_ERROR(WINDIVERT_ERROR_NONE, 0);
+ (PVOID)WinDivertCoalesceAndOr(pool, exprs, i, &err);
+ if (IS_ERROR(err))
{
- HeapDestroy(pool);
- return FALSE;
+ goto WinDivertHelperFormatFilterError;
}
}
@@ -4898,8 +4956,7 @@ BOOL WinDivertHelperFormatFilter(const char *filter, WINDIVERT_LAYER layer,
expr = WinDivertCoalesceExpr(pool, exprs, 0);
if (expr == NULL)
{
- HeapDestroy(pool);
- return FALSE;
+ goto WinDivertHelperFormatFilterError;
}
// Format the final expression:
@@ -4919,6 +4976,12 @@ BOOL WinDivertHelperFormatFilter(const char *filter, WINDIVERT_LAYER layer,
}
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
+
+WinDivertHelperFormatFilterError:
+ error = GetLastError();
+ HeapDestroy(pool);
+ SetLastError(error);
+ return FALSE;
}
/*
diff --git a/dll/windivert_shared.c b/dll/windivert_shared.c
index 6122405..0536d42 100644
--- a/dll/windivert_shared.c
+++ b/dll/windivert_shared.c
@@ -41,10 +41,10 @@
* Definitions to remove (some) external dependencies:
*/
#define BYTESWAP16(x) \
- ((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
+ ((((x) >> 8) & 0x00FFu) | (((x) << 8) & 0xFF00u))
#define BYTESWAP32(x) \
- ((((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | \
- (((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000))
+ ((((x) >> 24) & 0x000000FFu) | (((x) >> 8) & 0x0000FF00u) | \
+ (((x) << 8) & 0x00FF0000u) | (((x) << 24) & 0xFF000000u))
#define BYTESWAP64(x) \
((((x) >> 56) & 0x00000000000000FFull) | \
(((x) >> 40) & 0x000000000000FF00ull) | \
@@ -59,6 +59,20 @@
#define ntohl(x) BYTESWAP32(x)
#define htonl(x) BYTESWAP32(x)
+#if defined(WIN32) && defined(_MSC_VER)
+#pragma intrinsic(__emulu)
+static UINT64 WinDivertMul64(UINT64 a, UINT64 b)
+{
+ UINT64 r = __emulu((UINT32)a, (UINT32)b);
+ r += __emulu((UINT32)(a >> 32), (UINT32)b) << 32;
+ r += __emulu((UINT32)a, (UINT32)(b >> 32)) << 32;
+ return r;
+}
+#define WINDIVERT_MUL64(a, b) WinDivertMul64(a, b)
+#else /* WIN32 */
+#define WINDIVERT_MUL64(a, b) ((a) * (b))
+#endif /* WIN32 */
+
#include "windivert_hash.c"
/*
@@ -158,27 +172,26 @@ static char WinDivertEncodeDigit(UINT8 dig, BOOL final)
*/
static void WinDivertSerializeNumber(PWINDIVERT_STREAM stream, UINT32 val)
{
- UINT64 mask = 0x00000007C0000000ull;
+ UINT32 mask = 0xC0000000;
UINT dig = 6;
UINT8 digit;
- UINT64 val64 = (UINT64)val;
BOOL final;
- while ((mask & val64) == 0 && dig != 0)
+ while ((mask & val) == 0 && dig != 0)
{
- mask >>= 5;
+ mask = (dig == 6? 0x3E000000: mask >> 5);
dig--;
}
while (TRUE)
{
final = (dig == 0);
- digit = (UINT8)((mask & val64) >> (5 * dig));
+ digit = (UINT8)((mask & val) >> (5 * dig));
WinDivertPutChar(stream, WinDivertEncodeDigit(digit, final));
if (final)
{
break;
}
- mask >>= 5;
+ mask = (dig == 6? 0x3E000000: mask >> 5);
dig--;
}
}
@@ -249,8 +262,8 @@ static void WinDivertSerializeTest(PWINDIVERT_STREAM stream,
default:
break;
}
- WinDivertSerializeLabel(stream, filter->success);
- WinDivertSerializeLabel(stream, filter->failure);
+ WinDivertSerializeLabel(stream, (UINT16)filter->success);
+ WinDivertSerializeLabel(stream, (UINT16)filter->failure);
}
/*
diff --git a/examples/flowtrack/flowtrack.c b/examples/flowtrack/flowtrack.c
index a6e37fb..b80db2f 100644
--- a/examples/flowtrack/flowtrack.c
+++ b/examples/flowtrack/flowtrack.c
@@ -227,7 +227,7 @@ int __cdecl main(int argc, char **argv)
filter = argv[1];
break;
default:
- fprintf(stderr, "usage: %s [filter]\n");
+ fprintf(stderr, "usage: %s [filter]\n", argv[0]);
exit(EXIT_FAILURE);
}
diff --git a/examples/flowtrack/flowtrack.vcxproj b/examples/flowtrack/flowtrack.vcxproj
new file mode 100644
index 0000000..a2e2b53
--- /dev/null
+++ b/examples/flowtrack/flowtrack.vcxproj
@@ -0,0 +1,73 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MinSpace
+ Default
+ ..\..\include
+
+
+
+ flowtrack
+ flowtrack
+
+
+
+ v140
+ Application
+
+
+
+
+ ..\..\install\MSVC\i386\WinDivert.lib;shlwapi.lib;%(AdditionalDependencies)
+ ..\..\install\MSVC\amd64\WinDivert.lib;shlwapi.lib;%(AdditionalDependencies)
+
+
+
+
diff --git a/examples/netdump/netdump.vcxproj b/examples/netdump/netdump.vcxproj
new file mode 100644
index 0000000..1a90ec6
--- /dev/null
+++ b/examples/netdump/netdump.vcxproj
@@ -0,0 +1,73 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MinSpace
+ Default
+ ..\..\include
+
+
+
+ netdump
+ netdump
+
+
+
+ v140
+ Application
+
+
+
+
+ ..\..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)
+ ..\..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)
+
+
+
+
diff --git a/examples/netfilter/netfilter.vcxproj b/examples/netfilter/netfilter.vcxproj
new file mode 100644
index 0000000..a547d67
--- /dev/null
+++ b/examples/netfilter/netfilter.vcxproj
@@ -0,0 +1,73 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MinSpace
+ Default
+ ..\..\include
+
+
+
+ netfilter
+ netfilter
+
+
+
+ v140
+ Application
+
+
+
+
+ ..\..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)
+ ..\..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)
+
+
+
+
diff --git a/examples/passthru/passthru.vcxproj b/examples/passthru/passthru.vcxproj
new file mode 100644
index 0000000..40faa51
--- /dev/null
+++ b/examples/passthru/passthru.vcxproj
@@ -0,0 +1,73 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MinSpace
+ Default
+ ..\..\include
+
+
+
+ passthru
+ passthru
+
+
+
+ v140
+ Application
+
+
+
+
+ ..\..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)
+ ..\..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)
+
+
+
+
diff --git a/examples/socketdump/socketdump.c b/examples/socketdump/socketdump.c
index b4518db..1651fe8 100644
--- a/examples/socketdump/socketdump.c
+++ b/examples/socketdump/socketdump.c
@@ -88,8 +88,8 @@ int __cdecl main(int argc, char **argv)
}
// Fallthrough:
default:
- fprintf(stderr, "usage: %s [filter]\n");
- fprintf(stderr, " %s --block [filter]\n");
+ fprintf(stderr, "usage: %s [filter]\n", argv[0]);
+ fprintf(stderr, " %s --block [filter]\n", argv[0]);
exit(EXIT_FAILURE);
}
diff --git a/examples/socketdump/socketdump.vcxproj b/examples/socketdump/socketdump.vcxproj
new file mode 100644
index 0000000..c515229
--- /dev/null
+++ b/examples/socketdump/socketdump.vcxproj
@@ -0,0 +1,73 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MinSpace
+ Default
+ ..\..\include
+
+
+
+ socketdump
+ socketdump
+
+
+
+ v140
+ Application
+
+
+
+
+ ..\..\install\MSVC\i386\WinDivert.lib;shlwapi.lib;%(AdditionalDependencies)
+ ..\..\install\MSVC\amd64\WinDivert.lib;shlwapi.lib;%(AdditionalDependencies)
+
+
+
+
diff --git a/examples/streamdump/streamdump.vcxproj b/examples/streamdump/streamdump.vcxproj
new file mode 100644
index 0000000..567fe2b
--- /dev/null
+++ b/examples/streamdump/streamdump.vcxproj
@@ -0,0 +1,73 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MinSpace
+ Default
+ ..\..\include
+
+
+
+ streamdump
+ streamdump
+
+
+
+ v140
+ Application
+
+
+
+
+ ..\..\install\MSVC\i386\WinDivert.lib;ws2_32.lib;%(AdditionalDependencies)
+ ..\..\install\MSVC\amd64\WinDivert.lib;ws2_32.lib;%(AdditionalDependencies)
+
+
+
+
diff --git a/examples/webfilter/webfilter.vcxproj b/examples/webfilter/webfilter.vcxproj
new file mode 100644
index 0000000..b29ca0d
--- /dev/null
+++ b/examples/webfilter/webfilter.vcxproj
@@ -0,0 +1,73 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MinSpace
+ Default
+ ..\..\include
+
+
+
+ webfilter
+ webfilter
+
+
+
+ v140
+ Application
+
+
+
+
+ ..\..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)
+ ..\..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)
+
+
+
+
diff --git a/examples/windivertctl/windivertctl.c b/examples/windivertctl/windivertctl.c
index 7859420..5bb6ce9 100644
--- a/examples/windivertctl/windivertctl.c
+++ b/examples/windivertctl/windivertctl.c
@@ -87,7 +87,7 @@ int __cdecl main(int argc, char **argv)
{
usage:
fprintf(stderr, "usage: %s (list|watch|kill) [filter]\n", argv[0]);
- fprintf(stderr, " %s uninstall\n");
+ fprintf(stderr, " %s uninstall\n", argv[0]);
exit(EXIT_FAILURE);
}
if (strcmp(argv[1], "list") == 0)
diff --git a/examples/windivertctl/windivertctl.vcxproj b/examples/windivertctl/windivertctl.vcxproj
new file mode 100644
index 0000000..be36829
--- /dev/null
+++ b/examples/windivertctl/windivertctl.vcxproj
@@ -0,0 +1,73 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MinSpace
+ Default
+ ..\..\include
+
+
+
+ windivertctl
+ windivertctl
+
+
+
+ v140
+ Application
+
+
+
+
+ ..\..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)
+ ..\..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)
+
+
+
+
diff --git a/include/windivert.h b/include/windivert.h
index da1482e..26099c3 100644
--- a/include/windivert.h
+++ b/include/windivert.h
@@ -135,29 +135,37 @@ typedef struct
/*
* WinDivert address.
*/
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4201)
+#endif
typedef struct
{
INT64 Timestamp; /* Packet's timestamp. */
- UINT64 Layer:8; /* Packet's layer. */
- UINT64 Event:8; /* Packet event. */
- UINT64 Sniffed:1; /* Packet was sniffed? */
- UINT64 Outbound:1; /* Packet is outound? */
- UINT64 Loopback:1; /* Packet is loopback? */
- UINT64 Impostor:1; /* Packet is impostor? */
- UINT64 IPv6:1; /* Packet is IPv6? */
- UINT64 IPChecksum:1; /* Packet has valid IPv4 checksum? */
- UINT64 TCPChecksum:1; /* Packet has valid TCP checksum? */
- UINT64 UDPChecksum:1; /* Packet has valid UDP checksum? */
- UINT64 Reserved1:40;
+ UINT32 Layer:8; /* Packet's layer. */
+ UINT32 Event:8; /* Packet event. */
+ UINT32 Sniffed:1; /* Packet was sniffed? */
+ UINT32 Outbound:1; /* Packet is outound? */
+ UINT32 Loopback:1; /* Packet is loopback? */
+ UINT32 Impostor:1; /* Packet is impostor? */
+ UINT32 IPv6:1; /* Packet is IPv6? */
+ UINT32 IPChecksum:1; /* Packet has valid IPv4 checksum? */
+ UINT32 TCPChecksum:1; /* Packet has valid TCP checksum? */
+ UINT32 UDPChecksum:1; /* Packet has valid UDP checksum? */
+ UINT32 Reserved1:8;
+ UINT32 Reserved2;
union
{
WINDIVERT_DATA_NETWORK Network; /* Network layer data. */
WINDIVERT_DATA_FLOW Flow; /* Flow layer data. */
WINDIVERT_DATA_SOCKET Socket; /* Socket layer data. */
WINDIVERT_DATA_REFLECT Reflect; /* Reflect layer data. */
- UINT8 Reserved2[64];
+ UINT8 Reserved3[64];
};
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
/*
* WinDivert events.
@@ -321,6 +329,11 @@ extern WINDIVERTEXPORT BOOL WinDivertGetParam(
/* WINDIVERT HELPER API */
/****************************************************************************/
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4214)
+#endif
+
/*
* IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
*/
@@ -455,6 +468,10 @@ typedef struct
UINT16 Checksum;
} WINDIVERT_UDPHDR, *PWINDIVERT_UDPHDR;
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
/*
* Flags for WinDivertHelperCalcChecksums()
*/
diff --git a/include/windivert_device.h b/include/windivert_device.h
index 02783e4..70cea0f 100644
--- a/include/windivert_device.h
+++ b/include/windivert_device.h
@@ -287,12 +287,12 @@ typedef struct
*/
typedef struct
{
- UINT16 field:11; // WINDIVERT_FILTER_FIELD_*
- UINT16 test:5; // WINDIVERT_FILTER_TEST_*
- UINT16 success; // Success continuation.
- UINT16 failure; // Fail continuation.
- UINT16 neg:1; // Argument negative?
- UINT16 reserved:15;
+ UINT32 field:11; // WINDIVERT_FILTER_FIELD_*
+ UINT32 test:5; // WINDIVERT_FILTER_TEST_*
+ UINT32 success:16; // Success continuation.
+ UINT32 failure:16; // Fail continuation.
+ UINT32 neg:1; // Argument negative?
+ UINT32 reserved:15;
UINT32 arg[4]; // Argument.
} WINDIVERT_FILTER, *PWINDIVERT_FILTER;
#pragma pack(pop)
diff --git a/mingw-build.sh b/mingw-build.sh
index 6ef91f1..e1a66d2 100644
--- a/mingw-build.sh
+++ b/mingw-build.sh
@@ -66,7 +66,7 @@ do
CC="$ENV-gcc"
COPTS="-fno-ident -shared -Wall -Wno-pointer-to-int-cast -Os -Iinclude/
-Wl,--enable-stdcall-fixup -Wl,--entry=${MANGLE}WinDivertDllEntry"
- CLIBS="-lgcc -lkernel32 -ladvapi32 $MSVCRT"
+ CLIBS="-lkernel32 -ladvapi32 $MSVCRT"
STRIP="$ENV-strip"
DLLTOOL="$ENV-dlltool"
if [ -x "`which $CC`" ]
diff --git a/msvc-build.bat b/msvc-build.bat
new file mode 100644
index 0000000..509243f
--- /dev/null
+++ b/msvc-build.bat
@@ -0,0 +1,150 @@
+:: msvc-build.bat
+:: (C) 2019, all rights reserved,
+::
+:: This file is part of WinDivert.
+::
+:: WinDivert is free software: you can redistribute it and/or modify it under
+:: the terms of the GNU Lesser General Public License as published by the
+:: Free Software Foundation, either version 3 of the License, or (at your
+:: option) any later version.
+::
+:: This program is distributed in the hope that it will be useful, but
+:: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+:: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+:: License for more details.
+::
+:: You should have received a copy of the GNU Lesser General Public License
+:: along with this program. If not, see .
+::
+:: WinDivert is free software; you can redistribute it and/or modify it under
+:: the terms of the GNU General Public License as published by the Free
+:: Software Foundation; either version 2 of the License, or (at your option)
+:: any later version.
+::
+:: This program is distributed in the hope that it will be useful, but
+:: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+:: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+:: for more details.
+::
+:: You should have received a copy of the GNU General Public License along
+:: with this program; if not, write to the Free Software Foundation, Inc., 51
+:: Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+@echo off
+
+msbuild sys\windivert.vcxproj ^
+ /p:Configuration=Release ^
+ /p:platform=Win32 ^
+ /p:SignMode=Off ^
+ /p:OutDir=..\install\MSVC\i386\ ^
+ /p:AssemblyName=WinDivert32
+
+msbuild sys\windivert.vcxproj ^
+ /p:Configuration=Release ^
+ /p:platform=x64 ^
+ /p:SignMode=Off ^
+ /p:OutDir=..\install\MSVC\amd64\ ^
+ /p:AssemblyName=WinDivert64
+
+msbuild dll\windivert.vcxproj ^
+ /p:Configuration=Release ^
+ /p:platform=Win32 ^
+ /p:OutDir=..\install\MSVC\i386\
+move dll\WinDivert.lib install\MSVC\i386\.
+
+msbuild dll\windivert.vcxproj ^
+ /p:Configuration=Release ^
+ /p:platform=x64 ^
+ /p:OutDir=..\install\MSVC\amd64\
+move dll\WinDivert.lib install\MSVC\amd64\.
+
+msbuild examples\flowtrack\flowtrack.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=Win32 ^
+ /p:OutDir=..\..\install\MSVC\i386\
+
+msbuild examples\flowtrack\flowtrack.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=x64 ^
+ /p:OutDir=..\..\install\MSVC\amd64\
+
+msbuild examples\netdump\netdump.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=Win32 ^
+ /p:OutDir=..\..\install\MSVC\i386\
+
+msbuild examples\netdump\netdump.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=x64 ^
+ /p:OutDir=..\..\install\MSVC\amd64\
+
+msbuild examples\netfilter\netfilter.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=Win32 ^
+ /p:OutDir=..\..\install\MSVC\i386\
+
+msbuild examples\netfilter\netfilter.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=x64 ^
+ /p:OutDir=..\..\install\MSVC\amd64\
+
+msbuild examples\passthru\passthru.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=Win32 ^
+ /p:OutDir=..\..\install\MSVC\i386\
+
+msbuild examples\passthru\passthru.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=x64 ^
+ /p:OutDir=..\..\install\MSVC\amd64\
+
+msbuild examples\socketdump\socketdump.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=Win32 ^
+ /p:OutDir=..\..\install\MSVC\i386\
+
+msbuild examples\socketdump\socketdump.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=x64 ^
+ /p:OutDir=..\..\install\MSVC\amd64\
+
+msbuild examples\streamdump\streamdump.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=Win32 ^
+ /p:OutDir=..\..\install\MSVC\i386\
+
+msbuild examples\streamdump\streamdump.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=x64 ^
+ /p:OutDir=..\..\install\MSVC\amd64\
+
+msbuild examples\webfilter\webfilter.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=Win32 ^
+ /p:OutDir=..\..\install\MSVC\i386\
+
+msbuild examples\webfilter\webfilter.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=x64 ^
+ /p:OutDir=..\..\install\MSVC\amd64\
+
+msbuild examples\windivertctl\windivertctl.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=Win32 ^
+ /p:OutDir=..\..\install\MSVC\i386\
+
+msbuild examples\windivertctl\windivertctl.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=x64 ^
+ /p:OutDir=..\..\install\MSVC\amd64\
+
+msbuild test\test.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=Win32 ^
+ /p:OutDir=..\install\MSVC\i386\
+
+msbuild test\test.vcxproj ^
+ /p:Configuration=Release ^
+ /p:Platform=x64 ^
+ /p:OutDir=..\install\MSVC\amd64\
+
diff --git a/sys/windivert.c b/sys/windivert.c
index 711db36..5937c23 100644
--- a/sys/windivert.c
+++ b/sys/windivert.c
@@ -256,23 +256,23 @@ struct packet_s
{
LIST_ENTRY entry; // Entry for queue.
LONGLONG timestamp; // Packet timestamp.
- UINT64 layer:8; // Layer.
- UINT64 event:8; // Event.
- UINT64 sniffed:1; // Packet was sniffed?
- UINT64 outbound:1; // Packet is outound?
- UINT64 loopback:1; // Packet is loopback?
- UINT64 impostor:1; // Packet is impostor?
- UINT64 ipv6:1; // Packet is IPv6?
- UINT64 ip_checksum:1; // Packet has IPv4 checksum?
- UINT64 tcp_checksum:1; // Packet has TCP checksum?
- UINT64 udp_checksum:1; // Packet has UDP checksum?
- UINT64 match:1; // Packet matches filter?
- UINT64 padding:7; // Padding for alignment.
- UINT64 packet_size:32; // Packet total size.
+ UINT32 layer:8; // Layer.
+ UINT32 event:8; // Event.
+ UINT32 sniffed:1; // Packet was sniffed?
+ UINT32 outbound:1; // Packet is outound?
+ UINT32 loopback:1; // Packet is loopback?
+ UINT32 impostor:1; // Packet is impostor?
+ UINT32 ipv6:1; // Packet is IPv6?
+ UINT32 ip_checksum:1; // Packet has IPv4 checksum?
+ UINT32 tcp_checksum:1; // Packet has TCP checksum?
+ UINT32 udp_checksum:1; // Packet has UDP checksum?
+ UINT32 match:1; // Packet matches filter?
+ UINT32 padding:7; // Padding for alignment.
+ UINT32 packet_size; // Packet total size.
PVOID object; // Object associated with packet.
UINT32 priority; // Packet priority.
UINT32 packet_len; // Length of the packet.
- WINDIVERT_DATA_ALIGN UINT8 data[]; // Packet/layer data.
+ WINDIVERT_DATA_ALIGN UINT8 data[1]; // Packet/layer data.
};
typedef struct packet_s *packet_t;
@@ -280,7 +280,7 @@ typedef struct packet_s *packet_t;
((((size) + WINDIVERT_ALIGN_SIZE - 1) / WINDIVERT_ALIGN_SIZE) * \
WINDIVERT_ALIGN_SIZE)
#define WINDIVERT_PACKET_SIZE(layer_type, packet_len) \
- (sizeof(struct packet_s) + WINDIVERT_DATA_SIZE(sizeof(layer_type)) + \
+ (sizeof(struct packet_s)-1 + WINDIVERT_DATA_SIZE(sizeof(layer_type)) + \
(packet_len))
#define WINDIVERT_LAYER_DATA_PTR(packet) \
((packet)->data)
@@ -360,11 +360,11 @@ static void windivert_uninstall_callouts(context_t context,
extern VOID windivert_cleanup(IN WDFFILEOBJECT object);
extern VOID windivert_close(IN WDFFILEOBJECT object);
extern VOID windivert_destroy(IN WDFOBJECT object);
-extern NTSTATUS windivert_write(context_t context, WDFREQUEST request,
+static NTSTATUS windivert_write(context_t context, WDFREQUEST request,
req_context_t req_context);
-extern void NTAPI windivert_inject_complete(VOID *context,
+static void NTAPI windivert_inject_complete(VOID *context,
NET_BUFFER_LIST *packets, BOOLEAN dispatch_level);
-extern void NTAPI windivert_reinject_complete(VOID *context,
+static void NTAPI windivert_reinject_complete(VOID *context,
NET_BUFFER_LIST *packets, BOOLEAN dispatch_level);
static NTSTATUS windivert_notify(IN FWPS_CALLOUT_NOTIFY_TYPE type,
IN const GUID *filter_key, IN const FWPS_FILTER0 *filter);
@@ -514,7 +514,7 @@ static void windivert_reflect_event_notify(context_t context,
LONGLONG timestamp, WINDIVERT_EVENT event);
static void windivert_reflect_established_notify(context_t context,
LONGLONG timestamp);
-static void windivert_reflect_worker(IN WDFWORKITEM item);
+extern void windivert_reflect_worker(IN WDFWORKITEM item);
/*
* WinDivert sublayer GUIDs
@@ -1261,8 +1261,10 @@ driver_entry_exit:
/*
* WinDivert driver unload routine.
*/
-extern VOID windivert_unload(IN WDFDRIVER Driver)
+extern VOID windivert_unload(IN WDFDRIVER driver)
{
+ UNREFERENCED_PARAMETER(driver);
+
windivert_driver_unload();
}
@@ -1661,7 +1663,7 @@ static NTSTATUS windivert_install_callout(context_t context, UINT idx,
GUID callout_guid, filter_guid;
UINT32 callout_id;
WDFDEVICE device;
- HANDLE engine_handle;
+ HANDLE engine;
NTSTATUS status;
KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle);
@@ -1675,7 +1677,7 @@ static NTSTATUS windivert_install_callout(context_t context, UINT idx,
callout_guid = context->callout_guid[idx];
filter_guid = context->filter_guid[idx];
device = context->device;
- engine_handle = context->engine_handle;
+ engine = context->engine_handle;
KeReleaseInStackQueuedSpinLock(&lock_handle);
weight = (UINT64)priority;
@@ -1714,26 +1716,26 @@ static NTSTATUS windivert_install_callout(context_t context, UINT idx,
*callout_id_ptr = callout_id;
KeReleaseInStackQueuedSpinLock(&lock_handle);
}
- status = FwpmTransactionBegin0(engine_handle, 0);
+ status = FwpmTransactionBegin0(engine, 0);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("failed to begin WFP transaction", status);
FwpsCalloutUnregisterByKey0(&callout_guid);
return status;
}
- status = FwpmCalloutAdd0(engine_handle, &mcallout, NULL, NULL);
+ status = FwpmCalloutAdd0(engine, &mcallout, NULL, NULL);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("failed to add WFP callout", status);
goto windivert_install_callout_error;
}
- status = FwpmFilterAdd0(engine_handle, &filter, NULL, NULL);
+ status = FwpmFilterAdd0(engine, &filter, NULL, NULL);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("failed to add WFP filter", status);
goto windivert_install_callout_error;
}
- status = FwpmTransactionCommit0(engine_handle);
+ status = FwpmTransactionCommit0(engine);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("failed to commit WFP transaction", status);
@@ -1755,7 +1757,7 @@ static NTSTATUS windivert_install_callout(context_t context, UINT idx,
return STATUS_SUCCESS;
windivert_install_callout_error:
- FwpmTransactionAbort0(engine_handle);
+ FwpmTransactionAbort0(engine);
FwpsCalloutUnregisterByKey0(&callout_guid);
return status;
}
@@ -1768,7 +1770,7 @@ static void windivert_uninstall_callouts(context_t context,
{
KLOCK_QUEUE_HANDLE lock_handle;
UINT i;
- HANDLE engine_handle;
+ HANDLE engine;
BOOL installed;
GUID callout_guid, filter_guid;
NTSTATUS status;
@@ -1782,14 +1784,14 @@ windivert_uninstall_callouts_error:
DEBUG_ERROR("failed to delete filters and callouts", status);
return;
}
- engine_handle = context->engine_handle;
+ engine = context->engine_handle;
KeReleaseInStackQueuedSpinLock(&lock_handle);
- status = FwpmTransactionBegin0(engine_handle, 0);
+ status = FwpmTransactionBegin0(engine, 0);
if (!NT_SUCCESS(status))
{
// If the userspace app closes without closing the handle to
- // WinDivert, any actions on engine_handle fail because the
+ // WinDivert, any actions on engine fail because the
// RPC handle was closed first. So, this path is "normal" if
// the user's app crashed or never closed the WinDivert handle.
DEBUG_ERROR("failed to begin WFP transaction", status);
@@ -1801,7 +1803,7 @@ windivert_uninstall_callouts_error:
if (context->state != state)
{
KeReleaseInStackQueuedSpinLock(&lock_handle);
- FwpmTransactionAbort0(engine_handle);
+ FwpmTransactionAbort0(engine);
status = STATUS_INVALID_DEVICE_STATE;
DEBUG_ERROR("failed to delete filters and callouts", status);
return;
@@ -1815,13 +1817,13 @@ windivert_uninstall_callouts_error:
{
continue;
}
- status = FwpmFilterDeleteByKey0(engine_handle, &filter_guid);
+ status = FwpmFilterDeleteByKey0(engine, &filter_guid);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("failed to delete filter", status);
break;
}
- status = FwpmCalloutDeleteByKey0(engine_handle, &callout_guid);
+ status = FwpmCalloutDeleteByKey0(engine, &callout_guid);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("failed to delete callout", status);
@@ -1830,10 +1832,10 @@ windivert_uninstall_callouts_error:
}
if (!NT_SUCCESS(status))
{
- FwpmTransactionAbort0(engine_handle);
+ FwpmTransactionAbort0(engine);
goto windivert_uninstall_callouts_unregister;
}
- status = FwpmTransactionCommit0(engine_handle);
+ status = FwpmTransactionCommit0(engine);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("failed to commit WFP transaction", status);
@@ -1872,7 +1874,6 @@ extern VOID windivert_cleanup(IN WDFFILEOBJECT object)
{
KLOCK_QUEUE_HANDLE lock_handle;
PLIST_ENTRY entry;
- UINT i;
context_t context = windivert_context_get(object);
flow_t flow;
packet_t work, packet;
@@ -2074,7 +2075,7 @@ static void windivert_read_service_request(context_t context, packet_t packet,
PLIST_ENTRY entry;
PMDL dst_mdl;
UINT8 *layer_data, *src, *dst;
- ULONG dst_len, src_len, read_len;
+ ULONG dst_len, src_len, read_len = 0;
BOOL timeout;
packet_t new_packet;
req_context_t req_context;
@@ -2136,7 +2137,6 @@ static void windivert_read_service_request(context_t context, packet_t packet,
addr_len = 0;
addr_len_max = (UINT)req_context->addr_len;
addr_len_ptr = req_context->addr_len_ptr;
- read_len = 0;
i = 0;
while (TRUE)
{
@@ -2443,8 +2443,6 @@ static void windivert_read_service(context_t context)
BOOL timeout;
NTSTATUS status;
packet_t packet;
- req_context_t req_context;
- PWINDIVERT_ADDRESS addr;
timestamp = KeQueryPerformanceCounter(NULL).QuadPart;
KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle);
@@ -2513,7 +2511,7 @@ static NTSTATUS windivert_write(context_t context, WDFREQUEST request,
UINT8 layer;
UINT32 priority;
UINT64 flags, checksums;
- HANDLE handle, compl_handle;
+ HANDLE handle;
PNET_BUFFER_LIST buffers = NULL;
PWINDIVERT_ADDRESS addr;
UINT i, addr_len, addr_len_max;
@@ -2830,8 +2828,8 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request)
{
case IOCTL_WINDIVERT_RECV:
ioctl = (PWINDIVERT_IOCTL)inbuf;
- addr = (PWINDIVERT_ADDRESS)ioctl->recv.addr;
- addr_len_ptr = (UINT *)ioctl->recv.addr_len_ptr;
+ addr = (PWINDIVERT_ADDRESS)(ULONG_PTR)ioctl->recv.addr;
+ addr_len_ptr = (UINT *)(ULONG_PTR)ioctl->recv.addr_len_ptr;
addr_len = sizeof(WINDIVERT_ADDRESS);
if (addr_len_ptr != NULL)
{
@@ -2875,7 +2873,7 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request)
case IOCTL_WINDIVERT_SEND:
ioctl = (PWINDIVERT_IOCTL)inbuf;
- addr = (PWINDIVERT_ADDRESS)ioctl->send.addr;
+ addr = (PWINDIVERT_ADDRESS)(ULONG_PTR)ioctl->send.addr;
addr_len = ioctl->send.addr_len;
if (addr_len < sizeof(WINDIVERT_ADDRESS) ||
addr_len > WINDIVERT_BATCH_MAX * sizeof(WINDIVERT_ADDRESS))
@@ -2943,15 +2941,15 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
size_t inbuflen, outbuflen, ioctl_filter_len;
PWINDIVERT_IOCTL ioctl;
const WINDIVERT_FILTER *ioctl_filter, *filter;
- UINT8 layer;
- INT16 priority;
- UINT64 flags;
req_context_t req_context;
NTSTATUS status = STATUS_SUCCESS;
context_t context =
windivert_context_get(WdfRequestGetFileObject(request));
- UINT64 value, *valptr;
+ UINT64 *valptr;
+
UNREFERENCED_PARAMETER(queue);
+ UNREFERENCED_PARAMETER(out_length);
+ UNREFERENCED_PARAMETER(in_length);
DEBUG("IOCTL: I/O control request (context=%p)", context);
@@ -3126,11 +3124,11 @@ windivert_ioctl_bad_flags:
case IOCTL_WINDIVERT_STARTUP:
{
- BOOL inbound, outbound, ipv4, ipv6;
PEPROCESS process;
LONGLONG timestamp;
UINT64 filter_flags;
UINT32 process_id;
+ WINDIVERT_LAYER layer;
UINT8 filter_len;
ioctl = (PWINDIVERT_IOCTL)inbuf;
@@ -3165,8 +3163,8 @@ windivert_ioctl_bad_flags:
DEBUG_ERROR("failed to compile filter", status);
goto windivert_ioctl_exit;
}
- filter_len = ioctl_filter_len / sizeof(WINDIVERT_FILTER);
- process_id = (UINT32)PsGetProcessId(process);
+ filter_len = (UINT8)(ioctl_filter_len / sizeof(WINDIVERT_FILTER));
+ process_id = (UINT32)(ULONG_PTR)PsGetProcessId(process);
timestamp = KeQueryPerformanceCounter(NULL).QuadPart;
KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle);
@@ -3438,6 +3436,11 @@ static void windivert_outbound_network_v4_classify(
{
WINDIVERT_DATA_NETWORK network_data;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(meta_vals);
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0 || data == NULL)
{
@@ -3452,9 +3455,8 @@ static void windivert_outbound_network_v4_classify(
FWPS_FIELD_OUTBOUND_IPPACKET_V4_FLAGS) &
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_network_classify((context_t)filter->context, &network_data,
- /*ipv4=*/TRUE, /*outbound=*/TRUE, loopback, /*advance=*/0, data,
- result);
+ windivert_network_classify(context, &network_data, /*ipv4=*/TRUE,
+ /*outbound=*/TRUE, loopback, /*advance=*/0, data, result);
}
/*
@@ -3468,7 +3470,12 @@ static void windivert_outbound_network_v6_classify(
{
WINDIVERT_DATA_NETWORK network_data;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+ UNREFERENCED_PARAMETER(meta_vals);
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
+
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0 || data == NULL)
{
return;
@@ -3482,9 +3489,8 @@ static void windivert_outbound_network_v6_classify(
FWPS_FIELD_OUTBOUND_IPPACKET_V6_FLAGS) &
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_network_classify((context_t)filter->context, &network_data,
- /*ipv4=*/FALSE, /*outbound=*/TRUE, loopback, /*advance=*/0,
- data, result);
+ windivert_network_classify(context, &network_data, /*ipv4=*/FALSE,
+ /*outbound=*/TRUE, loopback, /*advance=*/0, data, result);
}
/*
@@ -3499,7 +3505,11 @@ static void windivert_inbound_network_v4_classify(
WINDIVERT_DATA_NETWORK network_data;
UINT advance;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
+
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0 || data == NULL)
{
return;
@@ -3520,8 +3530,8 @@ static void windivert_inbound_network_v4_classify(
FWPS_FIELD_INBOUND_IPPACKET_V4_SUB_INTERFACE_INDEX);
advance = meta_vals->ipHeaderSize;
- windivert_network_classify((context_t)filter->context, &network_data,
- /*ipv4=*/TRUE, /*outbound=*/FALSE, loopback, advance, data, result);
+ windivert_network_classify(context, &network_data, /*ipv4=*/TRUE,
+ /*outbound=*/FALSE, loopback, advance, data, result);
}
/*
@@ -3536,7 +3546,11 @@ static void windivert_inbound_network_v6_classify(
WINDIVERT_DATA_NETWORK network_data;
UINT advance;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
+
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0 || data == NULL)
{
return;
@@ -3557,8 +3571,8 @@ static void windivert_inbound_network_v6_classify(
FWPS_FIELD_INBOUND_IPPACKET_V6_SUB_INTERFACE_INDEX);
advance = meta_vals->ipHeaderSize;
- windivert_network_classify((context_t)filter->context, &network_data,
- /*ipv4=*/FALSE, /*outbound=*/FALSE, loopback, advance, data, result);
+ windivert_network_classify(context, &network_data, /*ipv4=*/FALSE,
+ /*outbound=*/FALSE, loopback, advance, data, result);
}
/*
@@ -3571,7 +3585,12 @@ static void windivert_forward_network_v4_classify(
OUT FWPS_CLASSIFY_OUT0 *result)
{
WINDIVERT_DATA_NETWORK network_data;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+ UNREFERENCED_PARAMETER(meta_vals);
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
+
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0 || data == NULL)
{
return;
@@ -3581,9 +3600,8 @@ static void windivert_forward_network_v4_classify(
FWPS_FIELD_IPFORWARD_V4_DESTINATION_INTERFACE_INDEX);
network_data.SubIfIdx = 0;
- windivert_network_classify((context_t)filter->context, &network_data,
- /*ipv4=*/TRUE, /*outbound=*/TRUE, /*loopback=*/FALSE, /*advance=*/0,
- data, result);
+ windivert_network_classify(context, &network_data, /*ipv4=*/TRUE,
+ /*outbound=*/TRUE, /*loopback=*/FALSE, /*advance=*/0, data, result);
}
/*
@@ -3596,7 +3614,12 @@ static void windivert_forward_network_v6_classify(
OUT FWPS_CLASSIFY_OUT0 *result)
{
WINDIVERT_DATA_NETWORK network_data;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+ UNREFERENCED_PARAMETER(meta_vals);
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
+
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0 || data == NULL)
{
return;
@@ -3606,9 +3629,8 @@ static void windivert_forward_network_v6_classify(
FWPS_FIELD_IPFORWARD_V6_DESTINATION_INTERFACE_INDEX);
network_data.SubIfIdx = 0;
- windivert_network_classify((context_t)filter->context, &network_data,
- /*ipv4=*/FALSE, /*outbound=*/TRUE, /*loopback=*/FALSE, /*advance=*/0,
- data, result);
+ windivert_network_classify(context, &network_data, /*ipv4=*/FALSE,
+ /*outbound=*/TRUE, /*loopback=*/FALSE, /*advance=*/0, data, result);
}
/*
@@ -3629,7 +3651,6 @@ static void windivert_network_classify(context_t context,
PNET_BUFFER buffer, buffer_fst, buffer_itr;
BOOL impostor, sniff_mode, ok;
WDFOBJECT object;
- PLIST_ENTRY old_entry;
const WINDIVERT_FILTER *filter;
LONGLONG timestamp;
NTSTATUS status;
@@ -3673,7 +3694,7 @@ static void windivert_network_classify(context_t context,
if (packet_state == FWPS_PACKET_INJECTED_BY_SELF ||
packet_state == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF)
{
- packet_priority = (UINT32)packet_context;
+ packet_priority = (UINT32)(ULONG_PTR)packet_context;
if (packet_priority <= priority)
{
WdfObjectDereference(object);
@@ -3821,6 +3842,10 @@ static void windivert_flow_established_v4_classify(
WINDIVERT_DATA_FLOW flow_data;
BOOL outbound, loopback;
UINT64 flow_id;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
flow_data.EndpointId = meta_vals->transportEndpointHandle;
flow_data.ParentEndpointId = meta_vals->parentEndpointHandle;
@@ -3846,8 +3871,8 @@ static void windivert_flow_established_v4_classify(
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
flow_id = meta_vals->flowHandle;
- windivert_flow_established_classify((context_t)filter->context,
- flow_id, &flow_data, /*ipv4=*/TRUE, outbound, loopback, result);
+ windivert_flow_established_classify(context, flow_id, &flow_data,
+ /*ipv4=*/TRUE, outbound, loopback, result);
}
/*
@@ -3862,6 +3887,10 @@ static void windivert_flow_established_v6_classify(
WINDIVERT_DATA_FLOW flow_data;
BOOL outbound, loopback;
UINT64 flow_id;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
flow_data.ProcessId = (UINT32)meta_vals->processId;
windivert_get_ipv6_addr(fixed_vals,
@@ -3885,8 +3914,8 @@ static void windivert_flow_established_v6_classify(
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
flow_id = meta_vals->flowHandle;
- windivert_flow_established_classify((context_t)filter->context,
- flow_id, &flow_data, /*ipv4=*/FALSE, outbound, loopback, result);
+ windivert_flow_established_classify(context, flow_id, &flow_data,
+ /*ipv4=*/FALSE, outbound, loopback, result);
}
/*
@@ -4031,8 +4060,11 @@ static void windivert_flow_delete_notify(UINT16 layer_id, UINT32 callout_id,
const WINDIVERT_FILTER *filter;
LONGLONG timestamp;
flow_t flow;
+
+ UNREFERENCED_PARAMETER(layer_id);
+ UNREFERENCED_PARAMETER(callout_id);
- flow = (flow_t)flow_context;
+ flow = (flow_t)(ULONG_PTR)flow_context;
if (flow == NULL)
{
return;
@@ -4092,6 +4124,10 @@ static void windivert_resource_assignment_v4_classify(
{
WINDIVERT_DATA_SOCKET socket_data;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
@@ -4115,8 +4151,8 @@ static void windivert_resource_assignment_v4_classify(
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_FLAGS) &
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_BIND, /*ipv4=*/TRUE,
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_BIND, /*ipv4=*/TRUE,
/*outbound=*/FALSE, loopback, result);
}
@@ -4131,6 +4167,10 @@ static void windivert_resource_assignment_v6_classify(
{
WINDIVERT_DATA_SOCKET socket_data;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
@@ -4154,8 +4194,8 @@ static void windivert_resource_assignment_v6_classify(
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_FLAGS) &
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_BIND, /*ipv4=*/FALSE,
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_BIND, /*ipv4=*/FALSE,
/*outbound=*/FALSE, loopback, result);
}
@@ -4170,6 +4210,10 @@ static void windivert_resource_release_v4_classify(
{
WINDIVERT_DATA_SOCKET socket_data;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
socket_data.EndpointId = meta_vals->transportEndpointHandle;
socket_data.ParentEndpointId = 0;
@@ -4188,8 +4232,8 @@ static void windivert_resource_release_v4_classify(
FWPS_FIELD_ALE_RESOURCE_RELEASE_V4_FLAGS) &
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE, /*ipv4=*/TRUE,
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE, /*ipv4=*/TRUE,
/*outbound=*/FALSE, loopback, result);
}
@@ -4204,6 +4248,10 @@ static void windivert_resource_release_v6_classify(
{
WINDIVERT_DATA_SOCKET socket_data;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
socket_data.EndpointId = meta_vals->transportEndpointHandle;
socket_data.ParentEndpointId = 0;
@@ -4222,8 +4270,8 @@ static void windivert_resource_release_v6_classify(
FWPS_FIELD_ALE_RESOURCE_RELEASE_V6_FLAGS) &
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE, /*ipv4=*/FALSE,
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE, /*ipv4=*/FALSE,
/*outbound=*/FALSE, loopback, result);
}
@@ -4239,6 +4287,10 @@ static void windivert_auth_connect_v4_classify(
WINDIVERT_DATA_SOCKET socket_data;
UINT32 flags;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
@@ -4270,8 +4322,8 @@ static void windivert_auth_connect_v4_classify(
loopback = ((flags & FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_CONNECT, /*ipv4=*/TRUE,
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_CONNECT, /*ipv4=*/TRUE,
/*outbound=*/TRUE, loopback, result);
}
@@ -4287,6 +4339,10 @@ static void windivert_auth_connect_v6_classify(
WINDIVERT_DATA_SOCKET socket_data;
UINT32 flags;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
@@ -4318,8 +4374,8 @@ static void windivert_auth_connect_v6_classify(
loopback = ((flags & FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_CONNECT, /*ipv4=*/FALSE,
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_CONNECT, /*ipv4=*/FALSE,
/*outbound=*/TRUE, loopback, result);
}
@@ -4334,6 +4390,10 @@ static void windivert_endpoint_closure_v4_classify(
{
WINDIVERT_DATA_SOCKET socket_data;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
socket_data.EndpointId = meta_vals->transportEndpointHandle;
socket_data.ParentEndpointId = meta_vals->parentEndpointHandle;
@@ -4355,9 +4415,9 @@ static void windivert_endpoint_closure_v4_classify(
FWPS_FIELD_ALE_ENDPOINT_CLOSURE_V4_FLAGS) &
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE,
- /*ipv4=*/TRUE, /*outbound=*/TRUE, loopback, result);
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE, /*ipv4=*/TRUE,
+ /*outbound=*/TRUE, loopback, result);
}
/*
@@ -4371,6 +4431,10 @@ static void windivert_endpoint_closure_v6_classify(
{
WINDIVERT_DATA_SOCKET socket_data;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
socket_data.EndpointId = meta_vals->transportEndpointHandle;
socket_data.ParentEndpointId = meta_vals->parentEndpointHandle;
@@ -4392,9 +4456,9 @@ static void windivert_endpoint_closure_v6_classify(
FWPS_FIELD_ALE_ENDPOINT_CLOSURE_V6_FLAGS) &
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE,
- /*ipv4=*/FALSE, /*outbound=*/TRUE, loopback, result);
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE, /*ipv4=*/FALSE,
+ /*outbound=*/TRUE, loopback, result);
}
/*
@@ -4408,6 +4472,10 @@ static void windivert_auth_listen_v4_classify(
{
WINDIVERT_DATA_SOCKET socket_data;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
@@ -4430,8 +4498,8 @@ static void windivert_auth_listen_v4_classify(
FWPS_FIELD_ALE_AUTH_LISTEN_V4_FLAGS) &
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_LISTEN, /*ipv4=*/TRUE,
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_LISTEN, /*ipv4=*/TRUE,
/*outbound=*/FALSE, loopback, result);
}
@@ -4446,6 +4514,10 @@ static void windivert_auth_listen_v6_classify(
{
WINDIVERT_DATA_SOCKET socket_data;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
@@ -4468,8 +4540,8 @@ static void windivert_auth_listen_v6_classify(
FWPS_FIELD_ALE_AUTH_LISTEN_V6_FLAGS) &
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_LISTEN, /*ipv4=*/FALSE,
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_LISTEN, /*ipv4=*/FALSE,
/*outbound=*/FALSE, loopback, result);
}
@@ -4485,6 +4557,10 @@ static void windivert_auth_recv_accept_v4_classify(
WINDIVERT_DATA_SOCKET socket_data;
UINT32 flags;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
@@ -4516,8 +4592,8 @@ static void windivert_auth_recv_accept_v4_classify(
loopback = ((flags & FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_ACCEPT, /*ipv4=*/TRUE,
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_ACCEPT, /*ipv4=*/TRUE,
/*outbound=*/FALSE, loopback, result);
}
@@ -4533,7 +4609,11 @@ static void windivert_auth_recv_accept_v6_classify(
WINDIVERT_DATA_SOCKET socket_data;
UINT32 flags;
BOOL loopback;
+ context_t context = (context_t)(ULONG_PTR)filter->context;
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(flow_context);
+
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
return;
@@ -4564,8 +4644,8 @@ static void windivert_auth_recv_accept_v6_classify(
loopback = ((flags & FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
- windivert_socket_classify((context_t)filter->context,
- &socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_ACCEPT, /*ipv4=*/FALSE,
+ windivert_socket_classify(context, &socket_data,
+ /*event=*/WINDIVERT_EVENT_SOCKET_ACCEPT, /*ipv4=*/FALSE,
/*outbound=*/FALSE, loopback, result);
}
@@ -4582,7 +4662,6 @@ static void windivert_socket_classify(context_t context,
WDFOBJECT object;
const WINDIVERT_FILTER *filter;
LONGLONG timestamp;
- NTSTATUS status;
// Get the timestamp.
timestamp = KeQueryPerformanceCounter(NULL).QuadPart;
@@ -4883,7 +4962,7 @@ static BOOL windivert_queue_work(context_t context, PVOID packet,
static void windivert_queue_packet(context_t context, packet_t packet)
{
KLOCK_QUEUE_HANDLE lock_handle;
- PLIST_ENTRY entry, old_entry;
+ PLIST_ENTRY old_entry;
packet_t old_packet;
LONGLONG timestamp;
BOOL timeout;
@@ -5190,9 +5269,8 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
PWINDIVERT_ICMPV6HDR icmpv6_header = NULL;
PWINDIVERT_TCPHDR tcp_header = NULL;
PWINDIVERT_UDPHDR udp_header = NULL;
- UINT16 ip, ttl;
UINT8 proto = 0;
- UINT header_len = 0, payload_len = 0;
+ UINT header_len = 0;
NTSTATUS status;
// Parse the headers:
@@ -5382,7 +5460,6 @@ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer,
UINT8 data8;
UINT16 data16;
UINT32 data32;
- NTSTATUS status;
switch (layer)
{
@@ -6202,7 +6279,7 @@ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer,
return FALSE;
}
}
- ip = (result? filter[ip].success: filter[ip].failure);
+ ip = (UINT16)(result? filter[ip].success: filter[ip].failure);
if (ip == WINDIVERT_FILTER_RESULT_ACCEPT)
{
return TRUE;
@@ -6521,7 +6598,7 @@ static LIST_ENTRY reflect_contexts; // All open (non-REFLECT) contexts.
static LIST_ENTRY reflect_waiters; // All open REFLECT contexts.
static WDFWORKITEM reflect_worker; // Reflect work item.
#pragma data_seg(push, stack, "PAGE")
-static UINT8 reflect_packet[WINDIVERT_REFLECT_PACKET_MAX];
+static char reflect_packet[WINDIVERT_REFLECT_PACKET_MAX];
#pragma data_seg(pop, stack)
/*
@@ -6632,7 +6709,6 @@ static void windivert_reflect_close_event(context_t context)
static PVOID windivert_reflect_packet(context_t context, ULONG *len_ptr)
{
KLOCK_QUEUE_HANDLE lock_handle;
- UINT16 total_len;
const WINDIVERT_FILTER *filter;
UINT16 filter_len;
WINDIVERT_STREAM stream;
@@ -6663,7 +6739,7 @@ static void windivert_reflect_event_notify(context_t context,
context_t waiter;
const WINDIVERT_FILTER *filter;
PVOID packet = NULL, process;
- ULONG packet_len;
+ ULONG packet_len = 0;
UINT64 flags;
BOOL match;
@@ -6770,7 +6846,7 @@ static void windivert_reflect_established_notify(context_t context,
/*
* WinDivert REFLECT worker.
*/
-static void windivert_reflect_worker(IN WDFWORKITEM item)
+void windivert_reflect_worker(IN WDFWORKITEM item)
{
KLOCK_QUEUE_HANDLE lock_handle;
PLIST_ENTRY entry;
@@ -6781,6 +6857,8 @@ static void windivert_reflect_worker(IN WDFWORKITEM item)
WDFOBJECT object;
WINDIVERT_LAYER layer;
+ UNREFERENCED_PARAMETER(item);
+
// All reflection events are serialized and handled by this worker.
// This ensures that we are always operating on a consistent "snapshot"
// of the WinDivert handle state. This worker also has exclusive control
diff --git a/sys/windivert.vcxproj b/sys/windivert.vcxproj
new file mode 100644
index 0000000..d0e1fc5
--- /dev/null
+++ b/sys/windivert.vcxproj
@@ -0,0 +1,84 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MaxSpeed
+ ..\include;..\dll
+
+
+
+ v4.5
+ 12.0
+ WinDivert
+ WinDivert
+
+
+
+ Windows7
+ true
+ WindowsKernelModeDriver10.0
+ Driver
+ KMDF
+ Desktop
+ DbgengKernelDebugger
+ false
+
+
+
+
+ false
+ _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions);NDIS60;UNICODE;_UNICODE;NDIS_SUPPORT_NDIS60;NT;BINARY_COMPATIBLE=0
+ _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);NDIS60;UNICODE;_UNICODE;NDIS_SUPPORT_NDIS60;NT;BINARY_COMPATIBLE=0
+
+
+ %(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib;$(DDK_LIB_PATH)\wdmsec.lib;$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)\fwpkclnt.lib;$(SDK_LIB_PATH)\uuid.lib
+
+
+
+
diff --git a/test/test.c b/test/test.c
index 3065214..492c5a1 100644
--- a/test/test.c
+++ b/test/test.c
@@ -915,7 +915,7 @@ int main(void)
passed[i] = run_test(upper_handle, filter, packet, packet_len, match,
&diff);
diff = 1000000 * diff / freq.QuadPart;
- printf("%.3u ", i);
+ printf("%.3u ", (unsigned)i);
if (passed[i])
{
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
@@ -982,7 +982,7 @@ int main(void)
printf("\n------------\n\n");
first = FALSE;
}
- printf("%.3u ", i);
+ printf("%.3u ", (unsigned)i);
SetConsoleTextAttribute(console, FOREGROUND_RED);
printf("FAILED");
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
@@ -1153,7 +1153,7 @@ static BOOL run_test(HANDLE inject_handle, const char *filter,
if (buf_len[idx] != packet_len)
{
fprintf(stderr, "error: packet length mis-match, expected (%u), got "
- "(%u)\n", packet_len, buf_len[idx]);
+ "(%u)\n", (unsigned)packet_len, buf_len[idx]);
goto failed;
}
iphdr = (PWINDIVERT_IPHDR)buf[idx];
@@ -1329,8 +1329,8 @@ static DWORD monitor_worker(LPVOID arg)
tests[i].packet->packet_len, &addr) != tests[i].match)
{
fprintf(stderr, "error: failed to match recompiled filter "
- "(test = %.3u, filter = \"%s\", err = %d)\n", i,
- tests[i].filter, GetLastError());
+ "(test = %.3u, filter = \"%s\" formatted = \"%s\", "
+ "err = %d)\n", i, tests[i].filter, filter_2, GetLastError());
exit(EXIT_FAILURE);
}
}
diff --git a/test/test.vcxproj b/test/test.vcxproj
new file mode 100644
index 0000000..6a6d8bc
--- /dev/null
+++ b/test/test.vcxproj
@@ -0,0 +1,73 @@
+
+
+
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+ false
+ MinSpace
+ Default
+ ..\include
+
+
+
+ test
+ test
+
+
+
+ v140
+ Application
+
+
+
+
+ ..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)
+ ..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)
+
+
+
+