mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[AFD_APITEST] Introduce a test for directly creating and using sockets via AFD. CORE-9810
The initial tests in send.c validate correct behavior of send/sendto on disconnected sockets (CORE-9810), fixed in r68129. However, the helper functions are generic, so they can be used for additional tests against AFD. Because AFD's create packet structure changes between Windows versions, the functions check the OS version to determine the right layout. Tests succeed on Win2003 as well as Win10.
This commit is contained in:
parent
31139640ea
commit
680d69d373
7 changed files with 572 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
|||
include_directories(include)
|
||||
|
||||
add_subdirectory(advapi32)
|
||||
add_subdirectory(afd)
|
||||
add_subdirectory(apphelp)
|
||||
add_subdirectory(appshim)
|
||||
add_subdirectory(atl)
|
||||
|
|
384
modules/rostests/apitests/afd/AfdHelpers.c
Normal file
384
modules/rostests/apitests/afd/AfdHelpers.c
Normal file
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
|
||||
* PURPOSE: Utility function definitions for calling AFD
|
||||
* COPYRIGHT: Copyright 2015-2018 Thomas Faber (thomas.faber@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#define DD_UDP_DEVICE_NAME L"\\Device\\Udp"
|
||||
|
||||
typedef struct _AFD_CREATE_PACKET_NT6 {
|
||||
DWORD EndpointFlags;
|
||||
DWORD GroupID;
|
||||
DWORD AddressFamily;
|
||||
DWORD SocketType;
|
||||
DWORD Protocol;
|
||||
DWORD SizeOfTransportName;
|
||||
WCHAR TransportName[1];
|
||||
} AFD_CREATE_PACKET_NT6, *PAFD_CREATE_PACKET_NT6;
|
||||
|
||||
NTSTATUS
|
||||
AfdCreateSocket(
|
||||
_Out_ PHANDLE SocketHandle,
|
||||
_In_ int AddressFamily,
|
||||
_In_ int SocketType,
|
||||
_In_ int Protocol)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
PFILE_FULL_EA_INFORMATION EaBuffer = NULL;
|
||||
ULONG EaLength;
|
||||
PAFD_CREATE_PACKET AfdPacket;
|
||||
PAFD_CREATE_PACKET_NT6 AfdPacket6;
|
||||
ULONG SizeOfPacket;
|
||||
ANSI_STRING EaName = RTL_CONSTANT_STRING(AfdCommand);
|
||||
UNICODE_STRING TcpTransportName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
|
||||
UNICODE_STRING UdpTransportName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
|
||||
UNICODE_STRING TransportName = SocketType == SOCK_STREAM ? TcpTransportName : UdpTransportName;
|
||||
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Afd\\Endpoint");
|
||||
|
||||
*SocketHandle = NULL;
|
||||
|
||||
if (LOBYTE(LOWORD(GetVersion())) >= 6)
|
||||
{
|
||||
SizeOfPacket = FIELD_OFFSET(AFD_CREATE_PACKET_NT6, TransportName) + TransportName.Length + sizeof(UNICODE_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
SizeOfPacket = FIELD_OFFSET(AFD_CREATE_PACKET, TransportName) + TransportName.Length + sizeof(UNICODE_NULL);
|
||||
}
|
||||
EaLength = SizeOfPacket + FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) + EaName.Length + sizeof(ANSI_NULL);
|
||||
|
||||
/* Set up EA Buffer */
|
||||
EaBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, EaLength);
|
||||
if (!EaBuffer)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
EaBuffer->NextEntryOffset = 0;
|
||||
EaBuffer->Flags = 0;
|
||||
EaBuffer->EaNameLength = EaName.Length;
|
||||
RtlCopyMemory(EaBuffer->EaName,
|
||||
EaName.Buffer,
|
||||
EaName.Length + sizeof(ANSI_NULL));
|
||||
EaBuffer->EaValueLength = SizeOfPacket;
|
||||
|
||||
if (LOBYTE(LOWORD(GetVersion())) >= 6)
|
||||
{
|
||||
AfdPacket6 = (PAFD_CREATE_PACKET_NT6)(EaBuffer->EaName + EaBuffer->EaNameLength + sizeof(ANSI_NULL));
|
||||
AfdPacket6->GroupID = 0;
|
||||
if (SocketType == SOCK_DGRAM)
|
||||
{
|
||||
AfdPacket6->EndpointFlags = AFD_ENDPOINT_CONNECTIONLESS;
|
||||
}
|
||||
else if (SocketType == SOCK_STREAM)
|
||||
{
|
||||
AfdPacket6->EndpointFlags = AFD_ENDPOINT_MESSAGE_ORIENTED;
|
||||
}
|
||||
AfdPacket6->AddressFamily = AddressFamily;
|
||||
AfdPacket6->SocketType = SocketType;
|
||||
AfdPacket6->Protocol = Protocol;
|
||||
AfdPacket6->SizeOfTransportName = TransportName.Length;
|
||||
RtlCopyMemory(AfdPacket6->TransportName,
|
||||
TransportName.Buffer,
|
||||
TransportName.Length + sizeof(UNICODE_NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
AfdPacket = (PAFD_CREATE_PACKET)(EaBuffer->EaName + EaBuffer->EaNameLength + sizeof(ANSI_NULL));
|
||||
AfdPacket->GroupID = 0;
|
||||
if (SocketType == SOCK_DGRAM)
|
||||
{
|
||||
AfdPacket->EndpointFlags = AFD_ENDPOINT_CONNECTIONLESS;
|
||||
}
|
||||
else if (SocketType == SOCK_STREAM)
|
||||
{
|
||||
AfdPacket->EndpointFlags = AFD_ENDPOINT_MESSAGE_ORIENTED;
|
||||
}
|
||||
AfdPacket->SizeOfTransportName = TransportName.Length;
|
||||
RtlCopyMemory(AfdPacket->TransportName,
|
||||
TransportName.Buffer,
|
||||
TransportName.Length + sizeof(UNICODE_NULL));
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DeviceName,
|
||||
OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
|
||||
0,
|
||||
0);
|
||||
|
||||
Status = NtCreateFile(SocketHandle,
|
||||
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatus,
|
||||
NULL,
|
||||
0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_OPEN_IF,
|
||||
0,
|
||||
EaBuffer,
|
||||
EaLength);
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, EaBuffer);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
AfdBind(
|
||||
_In_ HANDLE SocketHandle,
|
||||
_In_ const struct sockaddr *Address,
|
||||
_In_ ULONG AddressLength)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
PAFD_BIND_DATA BindInfo;
|
||||
ULONG BindInfoLength;
|
||||
HANDLE Event;
|
||||
|
||||
Status = NtCreateEvent(&Event,
|
||||
EVENT_ALL_ACCESS,
|
||||
NULL,
|
||||
NotificationEvent,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
BindInfoLength = FIELD_OFFSET(AFD_BIND_DATA, Address.Address[0].Address) +
|
||||
AddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
|
||||
BindInfo = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
BindInfoLength);
|
||||
if (!BindInfo)
|
||||
{
|
||||
NtClose(Event);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
BindInfo->ShareType = AFD_SHARE_UNIQUE;
|
||||
BindInfo->Address.TAAddressCount = 1;
|
||||
BindInfo->Address.Address[0].AddressType = Address->sa_family;
|
||||
BindInfo->Address.Address[0].AddressLength = AddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
|
||||
RtlCopyMemory(&BindInfo->Address.Address[0].Address,
|
||||
Address->sa_data,
|
||||
BindInfo->Address.Address[0].AddressLength);
|
||||
|
||||
Status = NtDeviceIoControlFile(SocketHandle,
|
||||
Event,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
IOCTL_AFD_BIND,
|
||||
BindInfo,
|
||||
BindInfoLength,
|
||||
BindInfo,
|
||||
BindInfoLength);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
NtWaitForSingleObject(Event, FALSE, NULL);
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, BindInfo);
|
||||
NtClose(Event);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
AfdConnect(
|
||||
_In_ HANDLE SocketHandle,
|
||||
_In_ const struct sockaddr *Address,
|
||||
_In_ ULONG AddressLength)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
PAFD_CONNECT_INFO ConnectInfo;
|
||||
ULONG ConnectInfoLength;
|
||||
HANDLE Event;
|
||||
|
||||
Status = NtCreateEvent(&Event,
|
||||
EVENT_ALL_ACCESS,
|
||||
NULL,
|
||||
NotificationEvent,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
ASSERT(FIELD_OFFSET(AFD_CONNECT_INFO, RemoteAddress.Address[0].Address) == 20);
|
||||
ConnectInfoLength = FIELD_OFFSET(AFD_CONNECT_INFO, RemoteAddress.Address[0].Address) +
|
||||
AddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
|
||||
ConnectInfo = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
ConnectInfoLength);
|
||||
if (!ConnectInfo)
|
||||
{
|
||||
NtClose(Event);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
||||
ConnectInfo->UseSAN = FALSE;
|
||||
ConnectInfo->Root = 0;
|
||||
ConnectInfo->Unknown = 0;
|
||||
ConnectInfo->RemoteAddress.TAAddressCount = 1;
|
||||
ConnectInfo->RemoteAddress.Address[0].AddressType = Address->sa_family;
|
||||
ConnectInfo->RemoteAddress.Address[0].AddressLength = AddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
|
||||
RtlCopyMemory(&ConnectInfo->RemoteAddress.Address[0].Address,
|
||||
Address->sa_data,
|
||||
ConnectInfo->RemoteAddress.Address[0].AddressLength);
|
||||
|
||||
Status = NtDeviceIoControlFile(SocketHandle,
|
||||
Event,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
IOCTL_AFD_CONNECT,
|
||||
ConnectInfo,
|
||||
ConnectInfoLength,
|
||||
NULL,
|
||||
0);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
NtWaitForSingleObject(Event, FALSE, NULL);
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ConnectInfo);
|
||||
NtClose(Event);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
AfdSend(
|
||||
_In_ HANDLE SocketHandle,
|
||||
_In_ const void *Buffer,
|
||||
_In_ ULONG BufferLength)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
AFD_SEND_INFO SendInfo;
|
||||
HANDLE Event;
|
||||
AFD_WSABUF AfdBuffer;
|
||||
|
||||
Status = NtCreateEvent(&Event,
|
||||
EVENT_ALL_ACCESS,
|
||||
NULL,
|
||||
NotificationEvent,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
AfdBuffer.buf = (PVOID)Buffer;
|
||||
AfdBuffer.len = BufferLength;
|
||||
SendInfo.BufferArray = &AfdBuffer;
|
||||
SendInfo.BufferCount = 1;
|
||||
SendInfo.TdiFlags = 0;
|
||||
SendInfo.AfdFlags = 0;
|
||||
|
||||
Status = NtDeviceIoControlFile(SocketHandle,
|
||||
Event,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
IOCTL_AFD_SEND,
|
||||
&SendInfo,
|
||||
sizeof(SendInfo),
|
||||
NULL,
|
||||
0);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
NtWaitForSingleObject(Event, FALSE, NULL);
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
NtClose(Event);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
AfdSendTo(
|
||||
_In_ HANDLE SocketHandle,
|
||||
_In_ const void *Buffer,
|
||||
_In_ ULONG BufferLength,
|
||||
_In_ const struct sockaddr *Address,
|
||||
_In_ ULONG AddressLength)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
AFD_SEND_INFO_UDP SendInfo;
|
||||
HANDLE Event;
|
||||
AFD_WSABUF AfdBuffer;
|
||||
PTRANSPORT_ADDRESS TransportAddress;
|
||||
ULONG TransportAddressLength;
|
||||
|
||||
Status = NtCreateEvent(&Event,
|
||||
EVENT_ALL_ACCESS,
|
||||
NULL,
|
||||
NotificationEvent,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
TransportAddressLength = FIELD_OFFSET(TRANSPORT_ADDRESS, Address[0].Address) +
|
||||
AddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
|
||||
TransportAddress = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
TransportAddressLength);
|
||||
if (!TransportAddress)
|
||||
{
|
||||
NtClose(Event);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
TransportAddress->TAAddressCount = 1;
|
||||
TransportAddress->Address[0].AddressType = Address->sa_family;
|
||||
TransportAddress->Address[0].AddressLength = AddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
|
||||
RtlCopyMemory(&TransportAddress->Address[0].Address,
|
||||
Address->sa_data,
|
||||
TransportAddress->Address[0].AddressLength);
|
||||
|
||||
AfdBuffer.buf = (PVOID)Buffer;
|
||||
AfdBuffer.len = BufferLength;
|
||||
RtlZeroMemory(&SendInfo, sizeof(SendInfo));
|
||||
SendInfo.BufferArray = &AfdBuffer;
|
||||
SendInfo.BufferCount = 1;
|
||||
SendInfo.AfdFlags = 0;
|
||||
SendInfo.TdiConnection.RemoteAddress = TransportAddress;
|
||||
SendInfo.TdiConnection.RemoteAddressLength = TransportAddressLength;
|
||||
|
||||
Status = NtDeviceIoControlFile(SocketHandle,
|
||||
Event,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
IOCTL_AFD_SEND_DATAGRAM,
|
||||
&SendInfo,
|
||||
sizeof(SendInfo),
|
||||
NULL,
|
||||
0);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
NtWaitForSingleObject(Event, FALSE, NULL);
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, TransportAddress);
|
||||
NtClose(Event);
|
||||
|
||||
return Status;
|
||||
}
|
41
modules/rostests/apitests/afd/AfdHelpers.h
Normal file
41
modules/rostests/apitests/afd/AfdHelpers.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
|
||||
* PURPOSE: Utility function declarations for calling AFD
|
||||
* COPYRIGHT: Copyright 2015 Thomas Faber (thomas.faber@reactos.org)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
NTSTATUS
|
||||
AfdCreateSocket(
|
||||
_Out_ PHANDLE SocketHandle,
|
||||
_In_ int AddressFamily,
|
||||
_In_ int SocketType,
|
||||
_In_ int Protocol);
|
||||
|
||||
NTSTATUS
|
||||
AfdBind(
|
||||
_In_ HANDLE SocketHandle,
|
||||
_In_ const struct sockaddr *Address,
|
||||
_In_ ULONG AddressLength);
|
||||
|
||||
NTSTATUS
|
||||
AfdConnect(
|
||||
_In_ HANDLE SocketHandle,
|
||||
_In_ const struct sockaddr *Address,
|
||||
_In_ ULONG AddressLength);
|
||||
|
||||
NTSTATUS
|
||||
AfdSend(
|
||||
_In_ HANDLE SocketHandle,
|
||||
_In_ const void *Buffer,
|
||||
_In_ ULONG BufferLength);
|
||||
|
||||
NTSTATUS
|
||||
AfdSendTo(
|
||||
_In_ HANDLE SocketHandle,
|
||||
_In_ const void *Buffer,
|
||||
_In_ ULONG BufferLength,
|
||||
_In_ const struct sockaddr *Address,
|
||||
_In_ ULONG AddressLength);
|
15
modules/rostests/apitests/afd/CMakeLists.txt
Normal file
15
modules/rostests/apitests/afd/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
include_directories(
|
||||
${REACTOS_SOURCE_DIR}/sdk/include/reactos/drivers)
|
||||
|
||||
list(APPEND SOURCE
|
||||
AfdHelpers.c
|
||||
send.c
|
||||
precomp.h)
|
||||
|
||||
add_executable(afd_apitest ${SOURCE} testlist.c)
|
||||
target_link_libraries(afd_apitest wine)
|
||||
set_module_type(afd_apitest win32cui)
|
||||
add_importlibs(afd_apitest ws2_32 msvcrt kernel32 ntdll)
|
||||
add_pch(afd_apitest precomp.h SOURCE)
|
||||
add_rostests_file(TARGET afd_apitest)
|
26
modules/rostests/apitests/afd/precomp.h
Normal file
26
modules/rostests/apitests/afd/precomp.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
|
||||
* PURPOSE: Precompiled header for afd_apitest
|
||||
* COPYRIGHT: Copyright 2018 Thomas Faber (thomas.faber@reactos.org)
|
||||
*/
|
||||
|
||||
#if !defined(_AFD_APITEST_PRECOMP_H_)
|
||||
#define _AFD_APITEST_PRECOMP_H_
|
||||
|
||||
#include <apitest.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <ndk/exfuncs.h>
|
||||
#include <ndk/iofuncs.h>
|
||||
#include <ndk/obfuncs.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <tcpioctl.h>
|
||||
#include <tdi.h>
|
||||
#include <afd/shared.h>
|
||||
|
||||
#include "AfdHelpers.h"
|
||||
|
||||
#endif /* _AFD_APITEST_PRECOMP_H_ */
|
95
modules/rostests/apitests/afd/send.c
Normal file
95
modules/rostests/apitests/afd/send.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
|
||||
* PURPOSE: Test for IOCTL_AFD_SEND/IOCTL_AFD_SEND_DATAGRAM
|
||||
* COPYRIGHT: Copyright 2015 Thomas Faber (thomas.faber@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
static
|
||||
void
|
||||
TestSend(void)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE SocketHandle;
|
||||
CHAR Buffer[32];
|
||||
struct sockaddr_in addr;
|
||||
|
||||
RtlZeroMemory(Buffer, sizeof(Buffer));
|
||||
|
||||
Status = AfdCreateSocket(&SocketHandle, AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
ok(Status == STATUS_SUCCESS, "AfdCreateSocket failed with %lx\n", Status);
|
||||
|
||||
Status = AfdSend(SocketHandle, NULL, 0);
|
||||
ok(Status == STATUS_INVALID_CONNECTION, "AfdSend failed with %lx\n", Status);
|
||||
|
||||
Status = AfdSend(SocketHandle, Buffer, sizeof(Buffer));
|
||||
ok(Status == STATUS_INVALID_CONNECTION, "AfdSend failed with %lx\n", Status);
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr("0.0.0.0");
|
||||
addr.sin_port = htons(0);
|
||||
|
||||
Status = AfdBind(SocketHandle, (const struct sockaddr *)&addr, sizeof(addr));
|
||||
ok(Status == STATUS_SUCCESS, "AfdBind failed with %lx\n", Status);
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr("8.8.8.8");
|
||||
addr.sin_port = htons(53);
|
||||
|
||||
Status = AfdConnect(SocketHandle, (const struct sockaddr *)&addr, sizeof(addr));
|
||||
ok(Status == STATUS_SUCCESS, "AfdConnect failed with %lx\n", Status);
|
||||
|
||||
Status = AfdSend(SocketHandle, NULL, 0);
|
||||
ok(Status == STATUS_SUCCESS, "AfdSend failed with %lx\n", Status);
|
||||
|
||||
Status = AfdSend(SocketHandle, Buffer, sizeof(Buffer));
|
||||
ok(Status == STATUS_SUCCESS, "AfdSend failed with %lx\n", Status);
|
||||
|
||||
NtClose(SocketHandle);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
TestSendTo(void)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE SocketHandle;
|
||||
CHAR Buffer[32];
|
||||
struct sockaddr_in addr;
|
||||
|
||||
RtlZeroMemory(Buffer, sizeof(Buffer));
|
||||
|
||||
Status = AfdCreateSocket(&SocketHandle, AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
ok(Status == STATUS_SUCCESS, "AfdCreateSocket failed with %lx\n", Status);
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr("0.0.0.0");
|
||||
addr.sin_port = htons(0);
|
||||
|
||||
Status = AfdBind(SocketHandle, (const struct sockaddr *)&addr, sizeof(addr));
|
||||
ok(Status == STATUS_SUCCESS, "AfdBind failed with %lx\n", Status);
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr("8.8.8.8");
|
||||
addr.sin_port = htons(53);
|
||||
|
||||
Status = AfdSendTo(SocketHandle, NULL, 0, (const struct sockaddr *)&addr, sizeof(addr));
|
||||
ok(Status == STATUS_SUCCESS, "AfdSendTo failed with %lx\n", Status);
|
||||
|
||||
Status = AfdSendTo(SocketHandle, Buffer, sizeof(Buffer), (const struct sockaddr *)&addr, sizeof(addr));
|
||||
ok(Status == STATUS_SUCCESS, "AfdSendTo failed with %lx\n", Status);
|
||||
|
||||
NtClose(SocketHandle);
|
||||
}
|
||||
|
||||
START_TEST(send)
|
||||
{
|
||||
TestSend();
|
||||
TestSendTo();
|
||||
}
|
10
modules/rostests/apitests/afd/testlist.c
Normal file
10
modules/rostests/apitests/afd/testlist.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#define STANDALONE
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func_send(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "send", func_send },
|
||||
{ 0, 0 }
|
||||
};
|
Loading…
Reference in a new issue