ntoskrnl/tests: Add test for WskAccept().
Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2d7a304c45
commit
7f34362d85
|
@ -1,5 +1,5 @@
|
|||
TESTDLL = ntoskrnl.exe
|
||||
IMPORTS = advapi32
|
||||
IMPORTS = advapi32 ws2_32
|
||||
|
||||
driver_IMPORTS = winecrt0 ntoskrnl
|
||||
driver_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native
|
||||
|
|
|
@ -169,11 +169,19 @@ struct socket_context
|
|||
|
||||
static void test_wsk_listen_socket(void)
|
||||
{
|
||||
const WSK_PROVIDER_LISTEN_DISPATCH *tcp_dispatch, *udp_dispatch;
|
||||
static const WSK_CLIENT_LISTEN_DISPATCH client_listen_dispatch;
|
||||
const WSK_PROVIDER_LISTEN_DISPATCH *dispatch;
|
||||
const WSK_PROVIDER_CONNECTION_DISPATCH *accept_dispatch;
|
||||
WSK_SOCKET *tcp_socket, *udp_socket, *accept_socket;
|
||||
struct socket_context context;
|
||||
struct sockaddr_in addr;
|
||||
LARGE_INTEGER timeout;
|
||||
NTSTATUS status;
|
||||
WSK_SOCKET *s;
|
||||
KEVENT event;
|
||||
IRP *irp;
|
||||
|
||||
irp = IoAllocateIrp(1, FALSE);
|
||||
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
|
||||
|
||||
status = provider_npi.Dispatch->WskSocket(NULL, AF_INET, SOCK_STREAM, IPPROTO_TCP,
|
||||
WSK_FLAG_LISTEN_SOCKET, &context, &client_listen_dispatch, NULL, NULL, NULL, NULL);
|
||||
|
@ -197,20 +205,118 @@ static void test_wsk_listen_socket(void)
|
|||
ok(wsk_irp->IoStatus.Status == STATUS_SUCCESS, "Got unexpected status %#x.\n", wsk_irp->IoStatus.Status);
|
||||
ok(wsk_irp->IoStatus.Information, "Got zero Information.\n");
|
||||
|
||||
s = (WSK_SOCKET *)wsk_irp->IoStatus.Information;
|
||||
dispatch = s->Dispatch;
|
||||
tcp_socket = (WSK_SOCKET *)wsk_irp->IoStatus.Information;
|
||||
tcp_dispatch = tcp_socket->Dispatch;
|
||||
|
||||
IoReuseIrp(wsk_irp, STATUS_UNSUCCESSFUL);
|
||||
IoSetCompletionRoutine(wsk_irp, irp_completion_routine, &irp_complete_event, TRUE, TRUE, TRUE);
|
||||
status = provider_npi.Dispatch->WskSocket(provider_npi.Client, AF_INET, SOCK_DGRAM, IPPROTO_UDP,
|
||||
WSK_FLAG_LISTEN_SOCKET, &context, &client_listen_dispatch, NULL, NULL, NULL, wsk_irp);
|
||||
ok(status == STATUS_PENDING, "Got unexpected status %#x.\n", status);
|
||||
status = KeWaitForSingleObject(&irp_complete_event, Executive, KernelMode, FALSE, NULL);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
ok(wsk_irp->IoStatus.Status == STATUS_SUCCESS, "Got unexpected status %#x.\n", wsk_irp->IoStatus.Status);
|
||||
ok(wsk_irp->IoStatus.Information, "Got zero Information.\n");
|
||||
|
||||
udp_socket = (WSK_SOCKET *)wsk_irp->IoStatus.Information;
|
||||
udp_dispatch = udp_socket->Dispatch;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(12345);
|
||||
|
||||
IoReuseIrp(wsk_irp, STATUS_UNSUCCESSFUL);
|
||||
IoSetCompletionRoutine(wsk_irp, irp_completion_routine, &irp_complete_event, TRUE, TRUE, TRUE);
|
||||
wsk_irp->IoStatus.Status = 0xdeadbeef;
|
||||
wsk_irp->IoStatus.Information = 0xdeadbeef;
|
||||
status = dispatch->Basic.WskCloseSocket(s, wsk_irp);
|
||||
status = udp_dispatch->WskBind(udp_socket, (SOCKADDR *)&addr, 0, wsk_irp);
|
||||
ok(status == STATUS_PENDING, "Got unexpected status %#x.\n", status);
|
||||
status = KeWaitForSingleObject(&irp_complete_event, Executive, KernelMode, FALSE, NULL);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
ok(wsk_irp->IoStatus.Status == STATUS_NOT_IMPLEMENTED, "Got unexpected status %#x.\n", wsk_irp->IoStatus.Status);
|
||||
ok(!wsk_irp->IoStatus.Information, "Got unexpected Information %#lx.\n",
|
||||
wsk_irp->IoStatus.Information);
|
||||
|
||||
IoReuseIrp(wsk_irp, STATUS_UNSUCCESSFUL);
|
||||
IoSetCompletionRoutine(wsk_irp, irp_completion_routine, &irp_complete_event, TRUE, TRUE, TRUE);
|
||||
status = udp_dispatch->Basic.WskCloseSocket(udp_socket, wsk_irp);
|
||||
ok(status == STATUS_PENDING, "Got unexpected status %#x.\n", status);
|
||||
status = KeWaitForSingleObject(&irp_complete_event, Executive, KernelMode, FALSE, NULL);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
ok(wsk_irp->IoStatus.Status == STATUS_SUCCESS, "Got unexpected status %#x.\n", wsk_irp->IoStatus.Status);
|
||||
|
||||
IoReuseIrp(wsk_irp, STATUS_UNSUCCESSFUL);
|
||||
IoSetCompletionRoutine(wsk_irp, irp_completion_routine, &irp_complete_event, TRUE, TRUE, TRUE);
|
||||
wsk_irp->IoStatus.Status = 0xdeadbeef;
|
||||
wsk_irp->IoStatus.Information = 0xdeadbeef;
|
||||
status = tcp_dispatch->WskBind(tcp_socket, (SOCKADDR *)&addr, 0, wsk_irp);
|
||||
ok(status == STATUS_PENDING, "Got unexpected status %#x.\n", status);
|
||||
status = KeWaitForSingleObject(&irp_complete_event, Executive, KernelMode, FALSE, NULL);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
ok(wsk_irp->IoStatus.Status == STATUS_SUCCESS, "Got unexpected status %#x.\n", wsk_irp->IoStatus.Status);
|
||||
ok(!wsk_irp->IoStatus.Information, "Got unexpected Information %#lx.\n",
|
||||
wsk_irp->IoStatus.Information);
|
||||
|
||||
timeout.QuadPart = -1000 * 10000;
|
||||
|
||||
IoReuseIrp(wsk_irp, STATUS_UNSUCCESSFUL);
|
||||
IoSetCompletionRoutine(wsk_irp, irp_completion_routine, &irp_complete_event, TRUE, TRUE, TRUE);
|
||||
status = tcp_dispatch->WskAccept(tcp_socket, 0, NULL, NULL, NULL, NULL, wsk_irp);
|
||||
ok(status == STATUS_PENDING, "Got unexpected status %#x.\n", status);
|
||||
|
||||
if (0)
|
||||
{
|
||||
/* Queuing another WskAccept in parallel with different irp results in Windows hang. */
|
||||
IoReuseIrp(irp, STATUS_UNSUCCESSFUL);
|
||||
IoSetCompletionRoutine(irp, irp_completion_routine, &event, TRUE, TRUE, TRUE);
|
||||
status = tcp_dispatch->WskAccept(tcp_socket, 0, NULL, NULL, NULL, NULL, irp);
|
||||
ok(status == STATUS_PENDING, "Got unexpected status %#x.\n", status);
|
||||
}
|
||||
|
||||
status = KeWaitForSingleObject(&irp_complete_event, Executive, KernelMode, FALSE, &timeout);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
ok(wsk_irp->IoStatus.Status == STATUS_SUCCESS, "Got unexpected status %#x.\n", wsk_irp->IoStatus.Status);
|
||||
ok(wsk_irp->IoStatus.Information, "Got zero Information.\n");
|
||||
|
||||
if (status == STATUS_SUCCESS && wsk_irp->IoStatus.Status == STATUS_SUCCESS)
|
||||
{
|
||||
accept_socket = (WSK_SOCKET *)wsk_irp->IoStatus.Information;
|
||||
accept_dispatch = accept_socket->Dispatch;
|
||||
|
||||
IoReuseIrp(wsk_irp, STATUS_UNSUCCESSFUL);
|
||||
IoSetCompletionRoutine(wsk_irp, irp_completion_routine, &irp_complete_event, TRUE, TRUE, TRUE);
|
||||
status = accept_dispatch->Basic.WskCloseSocket(accept_socket, wsk_irp);
|
||||
ok(status == STATUS_PENDING, "Got unexpected status %#x.\n", status);
|
||||
status = KeWaitForSingleObject(&irp_complete_event, Executive, KernelMode, FALSE, NULL);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
ok(wsk_irp->IoStatus.Status == STATUS_SUCCESS, "Got unexpected status %#x.\n", wsk_irp->IoStatus.Status);
|
||||
ok(!wsk_irp->IoStatus.Information, "Got unexpected Information %#lx.\n",
|
||||
wsk_irp->IoStatus.Information);
|
||||
}
|
||||
|
||||
/* WskAccept to be aborted by WskCloseSocket(). */
|
||||
IoReuseIrp(irp, STATUS_UNSUCCESSFUL);
|
||||
IoSetCompletionRoutine(irp, irp_completion_routine, &event, TRUE, TRUE, TRUE);
|
||||
status = tcp_dispatch->WskAccept(tcp_socket, 0, NULL, NULL, NULL, NULL, irp);
|
||||
ok(status == STATUS_PENDING, "Got unexpected status %#x.\n", status);
|
||||
|
||||
IoReuseIrp(wsk_irp, STATUS_UNSUCCESSFUL);
|
||||
IoSetCompletionRoutine(wsk_irp, irp_completion_routine, &irp_complete_event, TRUE, TRUE, TRUE);
|
||||
wsk_irp->IoStatus.Status = 0xdeadbeef;
|
||||
wsk_irp->IoStatus.Information = 0xdeadbeef;
|
||||
status = tcp_dispatch->Basic.WskCloseSocket(tcp_socket, wsk_irp);
|
||||
ok(status == STATUS_PENDING, "Got unexpected status %#x.\n", status);
|
||||
status = KeWaitForSingleObject(&irp_complete_event, Executive, KernelMode, FALSE, NULL);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
ok(wsk_irp->IoStatus.Status == STATUS_SUCCESS, "Got unexpected status %#x.\n", wsk_irp->IoStatus.Status);
|
||||
ok(!wsk_irp->IoStatus.Information, "Got unexpected Information %#lx.\n",
|
||||
wsk_irp->IoStatus.Information);
|
||||
|
||||
status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, &timeout);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
ok(irp->IoStatus.Status == STATUS_CANCELLED, "Got unexpected status %#x.\n", irp->IoStatus.Status);
|
||||
ok(!irp->IoStatus.Information, "Got unexpected Information %#lx.\n", irp->IoStatus.Information);
|
||||
IoFreeIrp(irp);
|
||||
}
|
||||
|
||||
static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "winsvc.h"
|
||||
#include "winioctl.h"
|
||||
#include "winternl.h"
|
||||
#include "winsock2.h"
|
||||
#include "wine/test.h"
|
||||
#include "wine/heap.h"
|
||||
|
||||
|
@ -513,10 +514,42 @@ static void test_driver3(void)
|
|||
DeleteFileA(filename);
|
||||
}
|
||||
|
||||
void test_driver4(void)
|
||||
static DWORD WINAPI wsk_test_thread(void *parameter)
|
||||
{
|
||||
static const WORD version = MAKEWORD(2, 2);
|
||||
struct sockaddr_in addr;
|
||||
int ret, err;
|
||||
WSADATA data;
|
||||
SOCKET s;
|
||||
|
||||
ret = WSAStartup(version, &data);
|
||||
ok(!ret, "WSAStartup() failed, ret %u.\n", ret);
|
||||
|
||||
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
ok(s != INVALID_SOCKET, "Error creating socket, WSAGetLastError() %u.\n", WSAGetLastError());
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(12345);
|
||||
addr.sin_addr.s_addr = htonl(0x7f000001);
|
||||
|
||||
ret = connect(s, (struct sockaddr *)&addr, sizeof(addr));
|
||||
while (ret && ((err = WSAGetLastError()) == WSAECONNREFUSED || err == WSAECONNABORTED))
|
||||
{
|
||||
SwitchToThread();
|
||||
ret = connect(s, (struct sockaddr *)&addr, sizeof(addr));
|
||||
}
|
||||
ok(!ret, "Error connecting, WSAGetLastError() %u.\n", WSAGetLastError());
|
||||
|
||||
closesocket(s);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_driver4(void)
|
||||
{
|
||||
char filename[MAX_PATH];
|
||||
SC_HANDLE service;
|
||||
HANDLE hthread;
|
||||
DWORD written;
|
||||
BOOL ret;
|
||||
|
||||
|
@ -532,7 +565,9 @@ void test_driver4(void)
|
|||
device = CreateFileA("\\\\.\\WineTestDriver4", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
|
||||
|
||||
hthread = CreateThread(NULL, 0, wsk_test_thread, NULL, 0, NULL);
|
||||
main_test();
|
||||
WaitForSingleObject(hthread, INFINITE);
|
||||
|
||||
ret = DeviceIoControl(device, IOCTL_WINETEST_DETACH, NULL, 0, NULL, 0, &written, NULL);
|
||||
ok(ret, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
|
|
Loading…
Reference in New Issue