diff --git a/dll/windivert.c b/dll/windivert.c index f2a40d9..1ec6c41 100644 --- a/dll/windivert.c +++ b/dll/windivert.c @@ -464,10 +464,11 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer, ioctl.initialize.layer = layer; ioctl.initialize.priority = (INT32)priority + WINDIVERT_PRIORITY_MAX; ioctl.initialize.flags = flags; + memset(&version, 0, sizeof(version)); version.magic = WINDIVERT_MAGIC_DLL; version.major = WINDIVERT_VERSION_MAJOR; version.minor = WINDIVERT_VERSION_MINOR; - memset(version.reserved, 0, sizeof(version.reserved)); + version.bits = 8 * sizeof(void *); if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_INITIALIZE, &ioctl, &version, sizeof(version), NULL)) { @@ -504,8 +505,8 @@ extern BOOL WinDivertRecv(HANDLE handle, PVOID pPacket, UINT packetLen, { WINDIVERT_IOCTL ioctl; memset(&ioctl, 0, sizeof(ioctl)); - ioctl.recv.addr = addr; - ioctl.recv.addr_len_ptr = NULL; + ioctl.recv.addr = (UINT64)addr; + ioctl.recv.addr_len_ptr = (UINT64)NULL; return WinDivertIoControl(handle, IOCTL_WINDIVERT_RECV, &ioctl, pPacket, packetLen, readLen); } @@ -519,8 +520,8 @@ extern BOOL WinDivertRecvEx(HANDLE handle, PVOID pPacket, UINT packetLen, { WINDIVERT_IOCTL ioctl; memset(&ioctl, 0, sizeof(ioctl)); - ioctl.recv.addr = addr; - ioctl.recv.addr_len_ptr = pAddrLen; + ioctl.recv.addr = (UINT64)addr; + ioctl.recv.addr_len_ptr = (UINT64)pAddrLen; if (flags != 0) { SetLastError(ERROR_INVALID_PARAMETER); @@ -546,7 +547,7 @@ extern BOOL WinDivertSend(HANDLE handle, const VOID *pPacket, UINT packetLen, { WINDIVERT_IOCTL ioctl; memset(&ioctl, 0, sizeof(ioctl)); - ioctl.send.addr = addr; + ioctl.send.addr = (UINT64)addr; ioctl.send.addr_len = sizeof(WINDIVERT_ADDRESS); return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, &ioctl, (PVOID)pPacket, packetLen, writeLen); @@ -561,7 +562,7 @@ extern BOOL WinDivertSendEx(HANDLE handle, const VOID *pPacket, UINT packetLen, { WINDIVERT_IOCTL ioctl; memset(&ioctl, 0, sizeof(ioctl)); - ioctl.send.addr = addr; + ioctl.send.addr = (UINT64)addr; ioctl.send.addr_len = addrLen; if (flags != 0) { @@ -587,7 +588,7 @@ extern BOOL WinDivertShutdown(HANDLE handle, WINDIVERT_SHUTDOWN how) { WINDIVERT_IOCTL ioctl; memset(&ioctl, 0, sizeof(ioctl)); - ioctl.shutdown.how = how; + ioctl.shutdown.how = (UINT32)how; return WinDivertIoControl(handle, IOCTL_WINDIVERT_SHUTDOWN, &ioctl, NULL, 0, NULL); } @@ -608,7 +609,7 @@ extern BOOL WinDivertSetParam(HANDLE handle, WINDIVERT_PARAM param, { WINDIVERT_IOCTL ioctl; memset(&ioctl, 0, sizeof(ioctl)); - ioctl.set_param.param = param; + ioctl.set_param.param = (UINT32)param; ioctl.set_param.val = value; return WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_PARAM, &ioctl, NULL, 0, NULL); @@ -622,7 +623,7 @@ extern BOOL WinDivertGetParam(HANDLE handle, WINDIVERT_PARAM param, { WINDIVERT_IOCTL ioctl; memset(&ioctl, 0, sizeof(ioctl)); - ioctl.get_param.param = param; + ioctl.get_param.param = (UINT32)param; return WinDivertIoControl(handle, IOCTL_WINDIVERT_GET_PARAM, &ioctl, pValue, sizeof(UINT64), NULL); } diff --git a/include/windivert_device.h b/include/windivert_device.h index e931a36..50aa833 100644 --- a/include/windivert_device.h +++ b/include/windivert_device.h @@ -230,18 +230,17 @@ typedef union { struct { - WINDIVERT_ADDRESS *addr; // WINDIVERT_ADDRESS pointer. - UINT *addr_len_ptr; // sizeof(addr) pointer. + UINT64 addr; // WINDIVERT_ADDRESS pointer. + UINT64 addr_len_ptr; // sizeof(addr) pointer. } recv; struct { - const WINDIVERT_ADDRESS *addr; - // WINDIVERT_ADDRESS pointer. + UINT64 addr; // WINDIVERT_ADDRESS pointer. UINT64 addr_len; // sizeof(addr). } send; struct { - WINDIVERT_LAYER layer; // Handle layer. + UINT32 layer; // Handle layer. UINT32 priority; // Handle priority. UINT64 flags; // Handle flags. } initialize; @@ -251,16 +250,16 @@ typedef union } startup; struct { - WINDIVERT_SHUTDOWN how; // WINDIVERT_SHUTDOWN_* + UINT32 how; // WINDIVERT_SHUTDOWN_* } shutdown; struct { - WINDIVERT_PARAM param; // WINDIVERT_PARAM_* + UINT32 param; // WINDIVERT_PARAM_* } get_param; struct { UINT64 val; // Value pointer. - WINDIVERT_PARAM param; // WINDIVERT_PARAM_* + UINT32 param; // WINDIVERT_PARAM_* } set_param; } WINDIVERT_IOCTL, *PWINDIVERT_IOCTL; @@ -272,7 +271,9 @@ typedef struct UINT64 magic; // Magic number (in/out). UINT32 major; // Driver major version (in/out). UINT32 minor; // Driver minor version (in/out). - UINT64 reserved[4]; + UINT32 bits; // 32 or 64 (in/out). + UINT32 reserved32[3]; + UINT64 reserved64[4]; } WINDIVERT_VERSION, *PWINDIVERT_VERSION; /* diff --git a/sys/windivert.c b/sys/windivert.c index b47dbdc..b1fcd01 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -2831,8 +2831,8 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request) { case IOCTL_WINDIVERT_RECV: ioctl = (PWINDIVERT_IOCTL)inbuf; - addr = ioctl->recv.addr; - addr_len_ptr = ioctl->recv.addr_len_ptr; + addr = (PWINDIVERT_ADDRESS)ioctl->recv.addr; + addr_len_ptr = (UINT *)ioctl->recv.addr_len_ptr; addr_len = sizeof(WINDIVERT_ADDRESS); if (addr_len_ptr != NULL) { @@ -2850,8 +2850,8 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request) addr_len > WINDIVERT_BATCH_MAX * sizeof(WINDIVERT_ADDRESS)) { status = STATUS_INVALID_PARAMETER; - DEBUG_ERROR("out-of-range address length for RECV ioctl", - status); + DEBUG_ERROR("out-of-range address length (%u) for RECV " + "ioctl", status, addr_len); goto windivert_caller_context_error; } if (addr == NULL) @@ -2882,8 +2882,8 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request) addr_len > WINDIVERT_BATCH_MAX * sizeof(WINDIVERT_ADDRESS)) { status = STATUS_INVALID_PARAMETER; - DEBUG_ERROR("out-of-range address length for RECV ioctl", - status); + DEBUG_ERROR("out-of-range address length (%u) for SEND ioctl", + status, addr_len); goto windivert_caller_context_error; } if (addr == NULL) @@ -3035,20 +3035,23 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, version = (WINDIVERT_VERSION *)outbuf; if (outbuflen != sizeof(WINDIVERT_VERSION) || version->magic != WINDIVERT_MAGIC_DLL || - version->major < WINDIVERT_VERSION_MAJOR_MIN) + version->major < WINDIVERT_VERSION_MAJOR_MIN || + (version->bits != 8 * sizeof(UINT32) && + version->bits != 8 * sizeof(UINT64))) { status = STATUS_INVALID_PARAMETER; - DEBUG_ERROR("failed to initialize; invalid init buffer", + DEBUG_ERROR("failed to initialize; invalid version buffer", status); goto windivert_ioctl_exit; } - layer = ioctl->initialize.layer; + layer = (WINDIVERT_LAYER)ioctl->initialize.layer; priority = ioctl->initialize.priority; flags = ioctl->initialize.flags; version->magic = WINDIVERT_MAGIC_SYS; version->major = WINDIVERT_VERSION_MAJOR; version->minor = WINDIVERT_VERSION_MINOR; + version->bits = 8 * sizeof(void *); switch ((UINT32)layer) { @@ -3200,7 +3203,7 @@ windivert_ioctl_bad_flags: WINDIVERT_SHUTDOWN how; ioctl = (PWINDIVERT_IOCTL)inbuf; - how = ioctl->shutdown.how; + how = (WINDIVERT_SHUTDOWN)ioctl->shutdown.how; KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle); if (context->state != WINDIVERT_CONTEXT_STATE_OPEN) { @@ -3233,10 +3236,11 @@ windivert_ioctl_bad_flags: case IOCTL_WINDIVERT_SET_PARAM: { - UINT64 param, value; + WINDIVERT_PARAM param; + UINT64 value; ioctl = (PWINDIVERT_IOCTL)inbuf; - param = ioctl->set_param.param; + param = (WINDIVERT_PARAM)ioctl->set_param.param; value = ioctl->set_param.val; KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle); if (context->state != WINDIVERT_CONTEXT_STATE_OPEN) @@ -3301,10 +3305,10 @@ windivert_ioctl_bad_flags: case IOCTL_WINDIVERT_GET_PARAM: { - UINT64 param; + WINDIVERT_PARAM param; ioctl = (PWINDIVERT_IOCTL)inbuf; - param = ioctl->get_param.param; + param = (WINDIVERT_PARAM)ioctl->get_param.param; if (outbuflen != sizeof(UINT64)) { status = STATUS_INVALID_PARAMETER; @@ -6270,7 +6274,9 @@ static const WINDIVERT_FILTER *windivert_filter_compile( break; case WINDIVERT_LAYER_SOCKET: if (event != WINDIVERT_EVENT_SOCKET_BIND && + event != WINDIVERT_EVENT_SOCKET_UNBIND && event != WINDIVERT_EVENT_SOCKET_CONNECT && + event != WINDIVERT_EVENT_SOCKET_DISCONNECT && event != WINDIVERT_EVENT_SOCKET_LISTEN && event != WINDIVERT_EVENT_SOCKET_ACCEPT) {