From 5d62e2a9386f2e182cf1fa444fe3811f68579ce8 Mon Sep 17 00:00:00 2001 From: basil00 Date: Fri, 19 Apr 2019 09:52:36 +0800 Subject: [PATCH] Add a Visual Studio build system (fix #118). Currently the VS build system targets VS2015, but may also work for later versions (not tested). To use: - Download & install VS2015. - Install WDK. - Open a Developer Command Prompt. - Run the msvc-build.bat script. --- dll/windivert.c | 129 ++++++++- dll/windivert.def | 1 - dll/windivert.vcxproj | 84 ++++++ dll/windivert_hash.c | 18 +- dll/windivert_helper.c | 299 ++++++++++++-------- dll/windivert_shared.c | 35 ++- examples/flowtrack/flowtrack.c | 2 +- examples/flowtrack/flowtrack.vcxproj | 73 +++++ examples/netdump/netdump.vcxproj | 73 +++++ examples/netfilter/netfilter.vcxproj | 73 +++++ examples/passthru/passthru.vcxproj | 73 +++++ examples/socketdump/socketdump.c | 4 +- examples/socketdump/socketdump.vcxproj | 73 +++++ examples/streamdump/streamdump.vcxproj | 73 +++++ examples/webfilter/webfilter.vcxproj | 73 +++++ examples/windivertctl/windivertctl.c | 2 +- examples/windivertctl/windivertctl.vcxproj | 73 +++++ include/windivert.h | 41 ++- include/windivert_device.h | 12 +- mingw-build.sh | 2 +- msvc-build.bat | 150 +++++++++++ sys/windivert.c | 300 +++++++++++++-------- sys/windivert.vcxproj | 84 ++++++ test/test.c | 10 +- test/test.vcxproj | 73 +++++ 25 files changed, 1541 insertions(+), 289 deletions(-) create mode 100644 dll/windivert.vcxproj create mode 100644 examples/flowtrack/flowtrack.vcxproj create mode 100644 examples/netdump/netdump.vcxproj create mode 100644 examples/netfilter/netfilter.vcxproj create mode 100644 examples/passthru/passthru.vcxproj create mode 100644 examples/socketdump/socketdump.vcxproj create mode 100644 examples/streamdump/streamdump.vcxproj create mode 100644 examples/webfilter/webfilter.vcxproj create mode 100644 examples/windivertctl/windivertctl.vcxproj create mode 100644 msvc-build.bat create mode 100644 sys/windivert.vcxproj create mode 100644 test/test.vcxproj 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) + + + +